java_微信公众号扫码绑定个人信息(微信公众号场景值二维码的使用)

看了一下网上关于公众号场景值二维码这方面的教程,基本上是微信官方开发文档的复制,没有具体实例。这里给出实例,并附加二维码url转文件流的方法。
思路:
1.后台传入个人信息保存,以个人信息的“业务类型编码+主键“”作为二维码场景值,换取微信ticket,再根据tiket获取二维码url,解析url生成文件流输出
2.微信后台监听用户扫码事件,从事件从获取场景值并解析出用户主键,取出用户并设置openid的值,就此绑定成功。

@RequestMapping(value = "/pInfoSubmit", method = RequestMethod.POST)
    public void login(HttpServletRequest request,HttpServletResponse response,
            RedirectAttributes model) throws UnsupportedEncodingException {
            //从头中解析出用户信息并保存,并用用户id构建场景值sceneId
            String name = request.getHeader("realName");
            String idCardNum =  request.getHeader("idCardNum");

            if (StringUtils.isNotBlank(name)
                    && StringUtils.isNotBlank(idCardNum)
                    && StringUtils.isNotBlank(phone)) {
                name = URLDecoder.decode(name, "UTF-8"); 
                address =URLDecoder.decode(address, "UTF-8");
                TjWxUser tjwxUser = new TjWxUser();
                tjwxUser.setRealName(name);
                tjwxUser.setIdentityNum(idCardNum);
                tjWxService.saveOrUpdateTjWxUser(tjwxUser);
                String sceneId = "wxUser" + tjwxUser.getId();
                String imageUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=";
                String ticket = WeiXinUtil.CreateQuickmarkTicket(sceneId);
                if (StringUtils.isNotBlank(ticket)) {
                    imageUrl += ticket;
                    //获取图片的文件流(根据url获取图片的文件流形式,)
                    getImage(response,imageUrl);
                }

            }

    }

public void getImage(HttpServletResponse response,String imageUrl){  
        try {    
               URL url = new URL(imageUrl);    
               HttpURLConnection conn = (HttpURLConnection)url.openConnection();    
               conn.setRequestMethod("GET");    
               conn.setConnectTimeout(5 * 1000);
               System.out.println("type:"+conn.getContentType());
               InputStream inStream = conn.getInputStream();//通过输入流获取图片数据    
            byte data[] = readInputStream(inStream);  
            inStream.read(data);  //读数据     
            inStream.close();     
            response.setContentType("image/jpg"); //设置返回的文件类型     
            OutputStream os = response.getOutputStream();    
            os.write(data);    
            os.flush();    
            os.close();   
           } catch (Exception e) {    
               e.printStackTrace();    
           }   
    }  


     public static byte[] readInputStream(InputStream inStream) throws Exception{    
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();    
            byte[] buffer = new byte[1024];    
            int len = 0;    
            while( (len=inStream.read(buffer)) != -1 ){    
                outStream.write(buffer, 0, len);    
            }    
            inStream.close();    
            return outStream.toByteArray();    
     }    

当然,在我看来更好的方式 是保存用户生成scenId以后进行带scenId值重定向,去微信官方获取二维码,不这么设计的原因是调用方是用pyhon写的,死活不认我的302重定向(人不为因素)。下面是扫码监听部分的代码:

 if ("SCAN".equals(event)) {
                    String eventKey = recvMsg.getEventKey();
                    if (StringUtils.isNotBlank(eventKey)) {
                    //从场景值中解析出用户id,注意“wxUser”和上面构建场景值使用的前缀一致。
                        TjWxUser wxUser = tjWxService.getTjWxUser(Integer
                                .parseInt(eventKey.replaceAll("wxUser", "")));
                        if (null != wxUser) {
                            TjWxUser user = tjWxService.getTjWxUserByOpenID(openId);
                            if (null!=user) {
                                user.setIdentityNum(wxUser.getIdentityNum());
                                user.setRealName(wxUser.getRealName());
                                tjWxService.saveOrUpdateTjWxUser(user);
  }

如果用户扫码前并没有关注你的公众号,触发的事件就不是这个扫码事件SCAN了,而是关注事件Subscribe,可以在Subsribe的监听部分也调用上图同样的绑定用户代码(写成一个公共的方法调用)。

阅读更多
换一批

没有更多推荐了,返回首页