- // 临时二维码
- private final static String QR_SCENE = "QR_SCENE";
- // 永久二维码
- private final static String QR_LIMIT_SCENE = "QR_LIMIT_SCENE";
- // 永久二维码(字符串)
- private final static String QR_LIMIT_STR_SCENE = "QR_LIMIT_STR_SCENE";
- // 创建二维码
- private String create_ticket_path = "https://api.weixin.qq.com/cgi-bin/qrcode/create";
- // 通过ticket换取二维码
- private String showqrcode_path = "https://mp.weixin.qq.com/cgi-bin/showqrcode";
- @RequestMapping("getQrcode")
- public @ResponseBody String getQrcode(@RequestParam(value = "sceneId")int sceneId) throws Exception{
- String ticket = createTempTicket(tokenService.getToken(),"2592000",sceneId);
- LOGGER.info("get wechat qrcode ==> start");
- LOGGER.info("sceneId :"+sceneId);
- LOGGER.info("ticket :"+ticket);
- LOGGER.info("get wechat qrcode ==> end");
- return ticket;
- }
- /**
- * 创建临时带参数二维码
- * @param accessToken
- * @expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。
- * @param sceneId 场景Id
- * @return
- */
- public String createTempTicket(String accessToken, String expireSeconds, int sceneId) {
- TreeMap<String,String> params = new TreeMap<String,String>();
- params.put("access_token", accessToken);
- Map<String,Integer> intMap = new HashMap<String,Integer>();
- intMap.put("scene_id",sceneId);
- Map<String,Map<String,Integer>> mapMap = new HashMap<String,Map<String,Integer>>();
- mapMap.put("scene", intMap);
- Map<String,Object> paramsMap = new HashMap<String,Object>();
- paramsMap.put("expire_seconds", expireSeconds);
- paramsMap.put("action_name", QR_SCENE);
- paramsMap.put("action_info", mapMap);
- String data = new Gson().toJson(paramsMap);
- String tse = HttpRequestUtil.HttpsDefaultExecute(HttpRequestUtil.POST_METHOD,create_ticket_path,params,data);
- JSONObject jsonObject = JSONObject.fromObject(tse);
- LOGGER.info("ticket :"+jsonObject.getString("ticket"));
- return showqrcode_path + "?ticket=" + jsonObject.getString("ticket");
- }
- accessToken就是调用微信接口的凭证token
(2)网站端:网站写一个调用微信生成二维码的接口
- @RequestMapping("getQrcode") public@ResponseBody Hashtable getQrcode(int sceneId) {
- System.out.println(sceneId);
- Hashtable param = new Hashtable();
- param.put("sceneId", sceneId);
- String qrcodePath = HttpUtil.postRequest(Constant.getValue("get_qrcode"), param);
- System.out.println(" qrcodePath ==> " + qrcodePath);
- param.put("path", qrcodePath);
- return param;
- }
直接使用http调用接口就行,Constant.getValue("get_qrcode")这个就是微信提供二维码接口的url
(3)微信端:微信处理用户请求(这个地址是微信公众号填的那个地址,微信服务器会将所有用户请求转发到这个地址)
- // 事件推送
- else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
- // 事件类型
- String eventType = requestMap.get("Event");
- // 关注
- if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
- //获取用户信息
- String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID";
- requestUrl = requestUrl.replace("ACCESS_TOKEN", tokenService.getToken()).replace("OPENID", fromUserName);
- JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);
- String nickname = jsonObject.getString("nickname");
- String address = jsonObject.getString("country") + "-" + jsonObject.getString("province") + "-" + jsonObject.getString("city");
- String headimgurl = jsonObject.getString("headimgurl");
- //将用户信息存入redis,key为唯一值(场景值)
- Hashtable params = new Hashtable();
- params.put("phoneIme", fromUserName);
- params.put("state", 1);
- params.put("location", address);
- params.put("realName", nickname);
- params.put("nickname", nickname);
- params.put("headimgurl", headimgurl);
- if (StringUtils.isNotBlank(eventKey)) {
- redisCacheTool.setDataToRedis(eventKey.replace("qrscene_", ""), 3600, params);
- System.out.println("qrcode redis key ==> " + eventKey.replace("qrscene_", ""));
- params.put("equipmentType", eventKey);
- } //入库
- HttpUtil.postRequest(Constant.getValue("UPDATE_USER"), params);
- }
- // 取消关注
- else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {
- // TODO 取消订阅后用户不会再收到公众账号发送的消息,因此不需要回复
- Hashtable params = new Hashtable();
- params.put("phoneIme", fromUserName);
- params.put("state", 0);
- HttpUtil.postRequest(Constant.getValue("UPDATE_USER_ANS"), params);
- }
- // 扫描带参数二维码
- else if (eventType.toLowerCase().equals(MessageUtil.EVENT_TYPE_SCAN)) {
- // TODO 处理扫描带参数二维码事件
- if (StringUtils.isNotBlank(eventKey)) {
- String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID";
- //获取用户信息
- requestUrl = requestUrl.replace("ACCESS_TOKEN", tokenService.getToken()).replace("OPENID", fromUserName);
- JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);
- String nickname = jsonObject.getString("nickname");
- String address = jsonObject.getString("country") + "-" + jsonObject.getString("province") + "-" + jsonObject.getString("city");
- String headimgurl = jsonObject.getString("headimgurl"); //将用户信息存入redis,key为唯一值(场景值)
- Hashtable params = new Hashtable();
- params.put("nickname", nickname);
- params.put("headimgurl", headimgurl);
- params.put("location", address);
- redisCacheTool.setDataToRedis(eventKey, 3600, params);
- System.out.println("qrcode redis key ==> " + eventKey);
- }
- respContent = "返回的信息";
- textMessage.setContent(respContent);
- respXml = MessageUtil.messageToXml(textMessage);
- }
(4)网站端:登陆页面中做轮训,每隔几秒查询一次redis,如果有用户信息就登陆
- var timestamp = new Date().getTime() + "";
- var str = timestamp.substring(8, timestamp.length);
- window.setInterval(function() {
- getUser(cont);
- },
- 10000);
- function getUser() {
- $.ajax({
- type: 'get',
- data: {
- sceneId: str
- },
- dataType: 'json',
- url: "getUser.do",
- success: function(data) {
- if (data.msg == "success") {
- location.reload();
- }
- },
- error: function(data) {
- if (data.msg == "success") {
- location.reload();
- }
- }
- });
- }
--本文意在对网站实现微信公众号用户扫码关注登录的实现思路做了概述
--这个方案中轮训访问是个问题,也是可以改进的地方,但是目前没有更好的方案,如果您有什么更好的建议,欢迎留言给点思路
来源: http://www.cnblogs.com/cmyxn/p/7803117.html