扫描二维码后,首先会跳转至二维码中的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到。