扫描二维码没有关注时跳转至关注界面

时间:2022-11-17 07:30:15

扫描二维码后,首先会跳转至二维码中的redirect_uri中的url,扫描二维码跳后台的方法可参考小编的另一篇博客《微信二维码扫码获取openid》

url的后台首先通过code 获取openid,通过openid获取Access_token,通过openid和Access_token获取subscribe

当subscribe=1时,说明已关注,当subscribe = 0时,说明未关注 ,则重定向至微信关注jian。

/** 注  测试公众不适用此方法,因为当用户没有关注时,不会跳转到url指定后台,而是会在页面提示该用户没有关注。个人的订阅号一般也是不行的,因为没有网页授权的那个接口的权限。小编测试的时候用的是公司的公众号。

下面来看代码:

public String queueInfo() throws Exception{
		HttpServletRequest request = (HttpServletRequest)ActionContext.getContext().get(org.apache.struts2.StrutsStatics.HTTP_REQUEST);  
		String code = request.getParameter("code");
		//通过code获取openid;
		net.sf.json.JSONObject wxUser = CoreService.getOpenid(code);
		String openid = wxUser.getString("openid");
		
		//获取subscribe
		net.sf.json.JSONObject userInfo = CoreService.getUserInfo(openid);
		String subscribe = userInfo.getString("subscribe");
		//未关注公众号
		if(!subscribe.equals("1")){
			HttpServletResponse response = (HttpServletResponse)  ActionContext.getContext().get(org.apache.struts2.StrutsStatics.HTTP_RESPONSE);  
			response.sendRedirect("https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz="+CoreService.BIZ+"&scene=110#wechat_redirect");  
			return null;
		}else{
			return "waitpage";
		}
	}
public class CoreService {
    public static String BIZ="abcdefg==";
public static String GETOPENID = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
public static String GET_USERINFO = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";

	public static JSONObject pushMessage(String path) throws IOException{
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		URL url = new URL(path);
		HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
		httpUrlConn.setRequestMethod("POST");
		httpUrlConn.setDoOutput(true);
		httpUrlConn.setDoInput(true);
		httpUrlConn.setUseCaches(false);
        // 将返回的输入流转换成字符串
        InputStream inputStream = httpUrlConn.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String str = null;
        while ((str = bufferedReader.readLine()) != null) {
            buffer.append(str);
        }
        bufferedReader.close();
        inputStreamReader.close();
        // 释放资源
        inputStream.close();
        inputStream = null;
        httpUrlConn.disconnect();
        jsonObject = JSONObject.fromObject(buffer.toString());
		return jsonObject;
	}
	
	/*通过code获取用户openid*/
	public static JSONObject getOpenid(String code) throws IOException{
		JSONObject jsonObject = null;
		String path = GETOPENID.replace("APPID", APPID).replace("SECRET", APPSECRET).replace("CODE", code);  
		jsonObject = pushMessage(path);
		return jsonObject;
	}
	
	/*获取用户信息*/
	public static JSONObject getUserInfo(String openid) throws Exception{
		String token = getToken();
		JSONObject jsonObject = null;
		String path = GET_USERINFO.replace("OPENID", openid).replace("ACCESS_TOKEN", token);  
		jsonObject = pushMessage(path);
		return jsonObject;
	}

	/*获取token*/
	public static String getToken() throws Exception{
		String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+APPSECRET;
		JSONObject jsonObject = pushMessage(url);
		String token = jsonObject.getString("ACCESS_TOKEN");
		return token;
	}
}

其实,在queueInfo()方法中,通过code获取的wxUser这个json对象中,有一个Access_token值,那为什么不在这里获取Access_token,而要在CoreService类中另写一个getToken方法去获取,这是不是多此一举了呢,其实不然。因为Access_token是一个凭证,它的有效期特别短,如果在queueInfo()方法中获取再传到CoreService类中的getUserInfo()方法中,就会报错:Access_token 不是最新的。因此要在getUserInfo()方法中再去重新获取一次最新的。

在没有关注公众号的时候,让程序重定向至关注页面,重定向的url中有一个值  _biz是公众号的一个值,该值类似于身份证,是唯一的。获取的方法百度一下教程很多,在这里稍作介绍。

打开公众号->点右上角的小人图标->查看历史消息->点右上角的三个点->复制链接->在除微信外的其他地方复制。得到类似如下url:https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=abcdefg==&scene=124#wechat_redirect

蓝色部分即为要的biz的值。

/**注 不适用与测试公众号,因为没有查看历史消息那个选项。测试公众号的获取方法小编目前也没有get到。