zoukankan      html  css  js  c++  java
  • 微信订阅号开发,获取openid的方式

    需求:微信订阅号开发,点击微信自定义菜单,获取关注用户的openid,并且传到后台与前端页面

    说明:订阅号无法直接获取关注用户的openid传到前端,只能通过微信开放平台将订阅号和服务号关联起来,获取用户的uionid,这样就可以确定当前操作的微信用户

    场景:

    1. 菜单类型为 view,创建view的代码:

    // 网页跳转菜单
    Map<String, String> menu1_1 = new HashMap<>();
    menu1_1.put("type", "view");
    menu1_1.put("name", "进入生态圈");
    menu1_1.put("url", "http://域名/menu/auth?redirect_uri=http://域名/menu/index");

    Controller 代码:

    /**
    * 授权入口:订阅号设置了业务域名后才会进入此方法
    * @param request
    * @param response
    */
    @RequestMapping(value = "/auth",method = RequestMethod.GET)
    @ResponseBody
    public void auth(HttpServletRequest request, HttpServletResponse response) {
        try {
    
            Map<String, String[]> paramterMap = request.getParameterMap();
            log.info("auth click Parameter: [");
            paramterMap.forEach((k,v)->{
                log.info("key : " + k + ";value : " + Arrays.toString(v));
            });
            log.info("]");
    
            // 跳转的URL必须要做encode
            String redirectUrl = URLEncoder.encode(request.getParameter("redirect_uri"), SysConst.ENCODE_UTF8);
    
            // 使用服务号的appid授权获取用户基本信息,然后跳转到redirect_uri,跳转到redirect_uri后,回接收到code
            String authUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+WeChatConfigDYH.APP_ID_FWH
            +"&redirect_uri="+redirectUrl
            +"&response_type=code&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect"; //跳转授权页面 response.sendRedirect(authUrl); } catch (Exception e) { e.printStackTrace(); } } /** * 授权接口跳转uri入口 * @param request * @param response */ @RequestMapping(value = "/index",method = RequestMethod.GET) public String index(HttpServletRequest request, HttpServletResponse response) { try { Map<String, String[]> paramterMap = request.getParameterMap(); log.info("view click Parameter: ["); paramterMap.forEach((k,v)->{ log.info("key : " + k + ";value : " + Arrays.toString(v)); }); log.info("]"); String code = request.getParameter("code"); log.debug("auth redirect_uri code = " + code); JSONObject weChatCode = _dataCache.getWeChatCode(code); if (weChatCode == null) { //通过code换取网页授权access_token(与基础支持中的access_token不同) String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+WeChatConfigDYH.APP_ID_FWH
              +"&secret="+WeChatConfigDYH.APP_SECRET_FWH
              +"&code="+code+"&grant_type=authorization_code"; //返回信息:包含unionid,标志唯一用户 String accessInfoStr = _restTemplate.getForObject(requestUrl, String.class); // 转化成JSONObject weChatCode = JSONObject.parseObject(accessInfoStr); // 存入缓存 _dataCache.putWeChatCode(code, weChatCode); } log.debug(weChatCode.toString()); // 微信unionid,唯一 String unionid = weChatCode.getString("unionid"); // 客户ID String fcustomerid495 = null; // 获取用户信息 Customer customer = _customerService.findByUnionId(unionid); if (customer != null) { fcustomerid495 = customer.getFcustomerid495(); } // 设置unionid和fcustomerid到前端 request.setAttribute("unionid", unionid); request.setAttribute("fcustomerid", fcustomerid495); } catch (Exception e) { e.printStackTrace(); } return "index"; }

    2. 菜单类型为 click 创建代码:

    // 按钮click
    Map<String, String> menu1_1 = new HashMap<>();
    menu1_1.put("type", "click");
    menu1_1.put("name", "进入生态圈");
    menu1_1.put("key", "self_edit");

    Controller代码:

    /**
    * 写法二
    * @param requestBody
    * @param signature
    * @param timestamp
    * @param nonce
    * @param openid
    * @param encType
    * @param msgSignature
    * @return
    */
    @RequestMapping(method = RequestMethod.POST)
    public String post(HttpServletRequest request, HttpServletResponse response,
            @RequestBody String requestBody,
            @RequestParam("signature") String signature,
            @RequestParam("timestamp") String timestamp,
            @RequestParam("nonce") String nonce,
            @RequestParam("openid") String openid,
            @RequestParam(name = "encrypt_type", required = false) String encType,
            @RequestParam(name = "msg_signature", required = false) String msgSignature) {
    
        // 返回给微信加密后的消息
        String respMessageEncrypt = "";
        try {
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
    
            Map<String, String> encryptMap = MessageUtil.fromEncryptedMap(requestBody, timestamp, nonce, msgSignature);
            log.info("菜单事件:" + encryptMap.toString());
    
            // 消息处理
            respMessageEncrypt = _weChatMessageService.newsMessage(encryptMap);
    
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
    
        }
    
        return respMessageEncrypt;
    }
    /**
    * 处理消息发送:图文消息
    * @param request
    * @return 加密消息字符传
    */
    public String newsMessage(Map<String, String> requestMap) {
        // 返回加密消息字符串
        String respMessageEncrypt = null;
        try {
            // 发送方帐号(open_id)
            String fromUserName = requestMap.get("FromUserName");
            // 公众帐号
            String toUserName = requestMap.get("ToUserName");
    
            // 根据openid获取客户信息
            String fcustomerid495 = null;
            Customer customer = _customerService.findByOpenId(fromUserName);
            if (customer != null) {
                fcustomerid495 = customer.getFcustomerid495();
            }
    
            // 设置链接消息
            NewsMessageResp newsMessage = new NewsMessageResp();
            newsMessage.setToUserName(fromUserName);
            newsMessage.setFromUserName(toUserName);
            newsMessage.setCreateTime(new Date().getTime());
            newsMessage.setMsgId(UUID.randomUUID().toString());
            newsMessage.setMsgType(WeChatConst.RESP_MESSAGE_TYPE_NEWS);
            newsMessage.setArticleCount("1");
    
            // Articles
            List<Article> articleList = new ArrayList<Article>();
            Article article = new Article();
            article.setTitle("生态圈链接");
            article.setDescription("点击进入【生态圈】");
            article.setPicUrl("http://域名/img/htlogo.png");
            article.setUrl("http://域名?openid=" + fromUserName + "&fcustomerid=" + fcustomerid495);
            articleList.add(article);
            newsMessage.setArticles(articleList);
    
            // 链接消息xml
            String respMessage = MessageUtil.newsMessageToXml(newsMessage);
            log.info("链接消息 = " + respMessage);
    
            // 消息加密
            WxCryptUtil wxCryptUtil = new WxCryptUtil();
            respMessageEncrypt = wxCryptUtil.encrypt(respMessage);
            log.info("加密后的链接消息 = " + respMessageEncrypt);
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        return respMessageEncrypt;
    }
     
  • 相关阅读:
    数组实现队列
    qsort用法 (转)
    枚举法
    HDU 2293
    bfs 街道赛跑
    漫谈二分查找Binary Search (转)
    qsort 结构体二级排序实例
    优化枚举法
    10项比较重要的.NET技术
    ADO.NET SQL Provider 和 ADO.NET OLE DB Provider 和 ADO.NET ODBC Provider 性能对比。
  • 原文地址:https://www.cnblogs.com/smartbear/p/11926868.html
Copyright © 2011-2022 走看看