End of the two-dimensional code scanning parameters event files public microcells number of attachment for user information and a check code for authenticity URL

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/qy_0626/article/details/86597544

This article is intended to record the two-dimensional code event article how to scan code with parameters for the original author please indicate the source of labor of respect for what I am very grateful

What is the two-dimensional code with the parameters of the event?

When we need to scan two-dimensional code number into the public and expect to do some custom business process, for example by someone who invited attention of the public number, business processing needs to be done to the man and the person of interest can be used with event parameters of two-dimensional code

Will give our development server push message when the user is not concerned about the attention and the two-dimensional code scanning parameters, it is convenient to do our business processes related scenes

Users swath scene when the value of two-dimensional code, may push the following two events:

  1. If the user has not yet concerned about the public number, the user can focus on the public number, after the scene with focus on micro-channel will focus on the value of the event pushed to developers.
  2. If the user has public concern number, the micro-channel will bring the value of scanning event scene pushed to developers.

Two-dimensional code scanning parameters, flow of events

1. Create a two-dimensional code with parameters (Note: call micro-channel interface to create a two-dimensional code)

2. exchange for two-dimensional code

3. Scan the QR code to accept the event push

Detailed Scan QR code to view the events push the official document : scan two-dimensional code with parameters event

text

The first step calls the micro-channel interface to create a two-dimensional code generation with parameters 

Two-dimensional code, there are two temporary and permanent temporary save up to a maximum of 30 days a permanent limit 100,000 as follows according to the developer's own business handling code:

/**
     * 生成临时/永久二维码
     * @param tel 代理标识 此处传值手机号
     * @param isLimitScene 是否是永久二维码 true 永久二维码 false 临时二维码
     * @param time 临时二维码时长 默认604800 单位秒 2592000 =30天
     * @return 更换二维码的ticket
     */
    @RequestMapping("wex/create_qrcode")
    @ResponseBody
    public Object createQrcode(String tel,@RequestParam(defaultValue = "true")Boolean isLimitScene,@RequestParam(defaultValue = "604800") int time){
        try {
            String access_token = wx.get_access_token();
            String url ="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";
            url=url.replace("TOKEN", access_token);
            JSONObject param = new JSONObject();
            if(isLimitScene){//永久二维码
                //二维码类型,QR_SCENE为临时的整型参数值,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久的整型参数值,QR_LIMIT_STR_SCENE为永久的字符串参数值
                param.put("action_name","QR_LIMIT_STR_SCENE");
            }else{
                param.put("action_name","QR_STR_SCENE");
                param.put("expire_seconds",time);//二维码生成后的30天(即2592000秒)后过期604800
            }
            param.put("action_info",new JSONObject().put("scene",new JSONObject().put("scene_str",tel)));//二维码的详细信息
            log.info("url:"+url);
            log.info("send data:"+param);
            String jsonstr = HttpUtil.postJsonForString(url,param);
            log.info("jsonstr:"+jsonstr);
            JSONObject jsonobj = new JSONObject(jsonstr);
            log.info("jsonobj:"+jsonobj);
//            String url2 = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";
//            url2=url2.replace("TICKET", jsonobj.get("ticket").toString());
//            String img = HttpUtil.getStringFromUrl(url2);
//            return jsonobj.get("ticket").toString();
            return jsonobj.toString();
        }catch (Exception e){
            e.printStackTrace();
            log.warn("error:"+e.getMessage());
        }
        return "";
    }

With parameters generated two-dimensional code official document : generate two-dimensional code with parameters

The second step or two-dimensional code by the ticket exchange url generate two-dimensional code

After the first step in creating yet we can not directly use the need to call in exchange for two-dimensional code interfaces where there are two ways to get to the two-dimensional code, a project I use the second method because it involves acquiring two-dimensional code generation to create a poster:

1. According ticket exchange for two-dimensional code

2. The two-dimensional code using the generated url component generates a two-dimensional code

By ticket exchange for two-dimensional code

After obtaining the two-dimensional code ticket, developers can ticket exchange for two-dimensional code images. Please note that this state can call the interface without logging in.

Request Description

HTTP GET请求(请使用https协议)https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET
提醒:TICKET记得进行UrlEncode

Returning to the description

Under the right circumstances ticket, http return code is 200, is a picture, you can directly display or download.

HTTP头(示例)如下:
Accept-Ranges:bytes
Cache-control:max-age=604800
Connection:keep-alive
Content-Length:28026
Content-Type:image/jpg
Date:Wed, 16 Oct 2013 06:37:10 GMT
Expires:Wed, 23 Oct 2013 14:37:10 +0800
Server:nginx/1.4.1

An error condition (e.g., illegal ticket) return an HTTP 404 error code.

The third step is to accept the message server developers to push the user to scan two-dimensional code

 If you want to receive push micro-channel server in our first public affirmation No. backstage turn on and configure the server  , the server needs to verify the authenticity of the configuration URL URL later turned on each method of micro-channel server to server developers push messages requesting this URL  to do a good job handling function Oh articles tail will attach the code check the authenticity of the URL Oh, here is the code that handles the developer to accept the micro-channel server push:

    @Autowired
    HttpServletRequest      request;

    /**
     * 处理服务器推送消息
     */
    @RequestMapping(value = "wex", method = { RequestMethod.GET, RequestMethod.POST })
    @ResponseBody
    public void liaotian(HttpServletRequest request, HttpServletResponse response) {
        try {
    		if(request.getMethod().equals("GET")){
    			log.info("++++++++++++++++++++++++校验URL真实性+++++++++++++++++++++++++++++++++");
    			access(request,response);
    		}else{
                WexHandeler();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //微信功能处理
    public String WexHandeler() throws Exception {
        try {
            JSONObject info = XML.toJSONObject(IOUtils.toString(request.getInputStream()));
//            info:
//            {
//                "xml": {
//                    "FromUserName": "oLqaP1sWgZqNIBWSUsNQlcz4Gsyg",
//                    "EventKey": "",
//                    "Event": "unsubscribe",
//                    "CreateTime": 1548060689,
//                    "ToUserName": "gh_2bc393a7842d",
//                    "MsgType": "event"
//                }
//            }

//            {
//                "xml": {
//                    "Ticket": "gQEY8TwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAycUVXOHhNS0NlZm0xc0IwZU5zMUYAAgSlhUVcAwSAOgkA",
//                    "FromUserName": "oLqaP1sWgZqNIBWSUsNQlcz4Gsyg",
//                    "EventKey": "qrscene_0",
//                    "Event": "subscribe",
//                    "CreateTime": 1548060879,
//                    "ToUserName": "gh_2bc393a7842d",
//                    "MsgType": "event"
//                }
//            }
            log.info("info:" + info);
            if (info.get("xml") != null) {
                JSONObject event = (JSONObject) info.get("xml");
                if (event.get("MsgType") != null) {
                    String Event = (String) event.get("Event");//事件类型 关注事件还是取消关注等
                    if (!StringUtils.isEmpty(Event)) { //如果是事件
                        try {
                            if ("subscribe".equals(Event)) {  //带参数二维码的关注事件
                                //关注方法
                                String toUserName = (String) event.get("ToUserName");//开发者微信号
                                String fromUserName = (String) event.get("FromUserName");//发送方帐号(一个OpenID)
                                String eventKey = (String) event.get("EventKey");//事件KEY值,是一个32位无符号整数,即创建二维码时的二维码scene_id
                                String ticket = (String) event.get("Ticket");//二维码的ticket,可用来换取二维码图片
                                log.info(">>>>>>>>>>>>>>>>>>接受的数据为:");
                                log.info("toUserName:"+toUserName);
                                log.info("fromUserName:"+fromUserName);
                                log.info("scene_id:"+eventKey);
                                log.info("ticket:"+ticket);
                                bindSuperior(fromUserName,eventKey);
                            } else if ("SCAN".equals(Event)) {//扫描带参数二维码事件 用户已关注时的事件推送
                                String toUserName = (String) event.get("ToUserName");//开发者微信号
                                String fromUserName = (String) event.get("FromUserName");//发送方帐号(一个OpenID)
                                String eventKey = (String) event.get("EventKey");//事件KEY值,是一个32位无符号整数,即创建二维码时的二维码scene_id
                                String ticket = (String) event.get("Ticket");//二维码的ticket,可用来换取二维码图片
                                log.info(">>>>>>>>>>>>>>>>>>接受的数据为:");
                                log.info("toUserName:"+toUserName);
                                log.info("fromUserName:"+fromUserName);
                                log.info("scene_id:"+eventKey);
                                log.info("ticket:"+ticket);
                                bindSuperior(fromUserName,eventKey);
                            } else if("unsubscribe".equals(Event)){

                            }
                        } catch (Exception e) {
                            return e.getMessage();
                        }
                    }
                }
            }
        } catch (Exception e) {
            return request.getParameter("echostr");
        }
        return request.getParameter("echostr");
    }

Appendix I check the authenticity URL

/**
     * 签名校验  验证URL真实性
     * @param request request
     * @param response response
     */
    protected void access(HttpServletRequest request, HttpServletResponse response) {
        try {
            System.out.println("开始签名校验");
            String signature = request.getParameter("signature");
            String timestamp = request.getParameter("timestamp");
            String nonce = request.getParameter("nonce");
            String echostr = request.getParameter("echostr");

            ArrayList<String> array = new ArrayList<String>();
            array.add(signature);
            array.add(timestamp);
            array.add(nonce);

            //排序
            String sortString = sort(token, timestamp, nonce);
            //加密
            String mytoken = Decript.SHA1(sortString);
            //校验签名
            if (mytoken != null && !mytoken.equals("") && mytoken.equals(signature)) {
                System.out.println("签名校验通过。");
                response.getWriter().println(echostr);
            } else {
                System.out.println("签名校验失败。");
            }
        }catch (Exception e){
            e.printStackTrace();
            log.warn("校验签名异常:"+e.getMessage());
        }
    }


    /**
     * 排序
     */
    public static String sort(String token, String timestamp, String nonce) {
        String[] strArray = { token, timestamp, nonce };
        Arrays.sort(strArray);

        StringBuilder sbuilder = new StringBuilder();
        for (String str : strArray) {
            sbuilder.append(str);
        }

        return sbuilder.toString();
    }

The user information acquiring Appendix II and access_token openid

    /**
     * 根据openid和access_token 获取用户信息
     * @param openid openid
     * @return Object 微信用户信息
     */
    @RequestMapping("wex/auth/userinfo")
    @ResponseBody
    public Object getUserInfoByOpenid(String openid){
        Map<String,Object> map = new HashMap<String, Object>();
        try {
            String access_token = wx.get_access_token();
            String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
            url=url.replace("ACCESS_TOKEN", access_token);
            url=url.replace("OPENID", openid);
            String jsonstr = HttpUtil.getStringFromUrl(url);
//            JSONObject jsonobj = new JSONObject(jsonstr);
            map.put(RETINFO.RET_CODE,RETINFO.RET_CODE_SUCCESS);
            map.put(RETINFO.RET_DATA,jsonstr);
            log.info("return data map:" + map);
            return map;
        }catch (Exception e){
           log.warn("获取授权用户信息异常:"+e.getMessage());
           e.printStackTrace();
           map.put(RETINFO.RET_CODE,RETINFO.RET_CODE_ERROR);
           map.put(RETINFO.RET_MSG,e.getMessage());
           return map;
        }
    }

Appendix III to obtain authorization signature page jssdk

/**
     * 网页授权签名生成
     * @param curr_url 授权的当前地址
     * @return 签名信息
     * @throws Exception
     */
    @RequestMapping("wex/auth/get_signature")
    public @ResponseBody  Map<String, Object> getSignatureForWexPublic(String curr_url) throws Exception {
        Map retMap = new HashMap<String, Object>();
        System.out.println("获取jssdk签名---->>>>>>>>>>>>>>>"+curr_url);
        try {

            String timestamp = Long.toString(System.currentTimeMillis() / 1000);
            String noncestr = UUID.randomUUID().toString();
            String url = java.net.URLDecoder.decode(curr_url, "utf-8");
            if(url.indexOf("#")>=0){
                url = url.substring(0, url.indexOf("#"));
            }
            //获取全局access_token
            String accessToken = wx.get_access_token();
            //获取jsapi的 jsapi_ticket
            String jsapi_ticket = wx.get_ticket();
            String preSiger = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url="
                    + url;
            String signature = DigestUtils.shaHex(preSiger);
            System.out.println("accessToken----->>>>"+accessToken+">>>>>>>>>>>>>>>>");
            System.out.println("jsapi_ticket----->>>>"+jsapi_ticket+">>>>>>>>>>>>>>>>");
            System.out.println("signature----->>>>"+signature+">>>>>>>>>>>>>>>>");

            //配置
            retMap.put(RETINFO.RET_CODE, RETINFO.RET_CODE_SUCCESS);
            retMap.put(RETINFO.RET_MSG, "执行成功");
            retMap.put("appid", appid);
            retMap.put("noncestr", noncestr);
            retMap.put("timestamp", timestamp);
            retMap.put("signature", signature);
            return retMap;
        } catch (Exception e) {
            retMap.put(RETINFO.RET_CODE, RETINFO.RET_CODE_ERROR);
            retMap.put(RETINFO.RET_MSG, "未获取到签名"+e.getMessage());
            return retMap;
        }
    }

 Appendix IV to obtain user information according to code

/**
     * 根据code获取授权用户信息
     * @param code code
     * @return 微信用户信息
     */
    @RequestMapping("wex/auth")
    @ResponseBody
    public Object getOpenidByAuto(String code){
        Map<String,Object> map = new HashMap<String, Object>();

        String openid="";
        try {
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
            url=url.replace("APPID", appid);
            url=url.replace("SECRET", appSecret);
            url=url.replace("CODE", code);
            String jsonstr = HttpUtil.getStringFromUrl(url);
            JSONObject jsonobj = new JSONObject(jsonstr);
            openid = jsonobj.getString("openid");
            log.warn("返回数据:"+jsonobj);
            map.put(RETINFO.RET_CODE,RETINFO.RET_CODE_SUCCESS);
            map.put(RETINFO.RET_DATA,openid);
            log.info("return data :" + map);
            return map;
        } catch (Exception e) {
            log.warn("根据code获取授权access_token异常:"+e.getMessage());
            e.printStackTrace();
            map.put(RETINFO.RET_CODE,RETINFO.RET_CODE_ERROR);
            map.put(RETINFO.RET_MSG,e.getMessage());
            return map;
        }
    }

 

Guess you like

Origin blog.csdn.net/qy_0626/article/details/86597544