微信开发对接

首先,本地开发调试 微信接口

1: 服务器配置

 2:代码里必须有一个 checkSign 的get请求。(这个方法是微信自动调用的)

/**
 * 响应get请求,微信默认token校验时使用get请求
 */
@GetMapping(value = "checkSign")
protected void checkSign(HttpServletRequest req, HttpServletResponse resp)
   {
   //接收微信用来校验信息的内置规定参数
   String signature = req.getParameter("signature");
   String timestamp = req.getParameter("timestamp");
   String nonce = req.getParameter("nonce");
   String echostr = req.getParameter("echostr");

      PrintWriter out = null;
      try {
         out = resp.getWriter();
         //按微信指定的规则进行校验并做出响应
         if (CheckSignatureUtil.checkSignature(signature, timestamp, nonce)) {
            out.print(echostr);
            out.flush();
         }
      } catch (IOException e) {
         e.printStackTrace();
      }finally {
         if(null != out){
            out.close();
         }
      }
}

3:业务相关 同样的方法名 checkSign,但是为post 请求

/**
    * 响应post请求,微信中消息和菜单交互都是采用post请求
    */

   @RequestMapping(value = "checkSign", method = RequestMethod.POST)
   protected String doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
      req.setCharacterEncoding("UTF-8");
      resp.setCharacterEncoding("UTF-8");
//    PrintWriter out = resp.getWriter();
      String message = null;
      try {
         //把微信返回的xml信息转义成map
         Map<String, String> map = XmlUtil.xmlToMap(req);

         log.info("微信事件触发==============" + JSON.toJSONString(map));

         //消息来源用户标识
         String fromUserName = map.get("FromUserName");
         //消息目的用户标识
         String toUserName = map.get("ToUserName");
         //消息类型
         String msgType = map.get("MsgType");
         //消息内容 用户输入内容
         String content = map.get("Content");

         String eventType = map.get("Event");
         //如果为事件类型
         if (MessageUtil.MSGTYPE_EVENT.equals(msgType)) {
            // userId-类型-公司名-国家 eg:
            String sceneStr = map.get("EventKey");
            if (MessageUtil.MESSAGE_SUBSCIBE.equals(eventType)){
               if(StringUtils.isNotBlank(sceneStr) && sceneStr.contains("-")){
                  // 添加扫码记录到datathink 下表中
                  String[] split = sceneStr.split("-");
                  String userID = split[0].substring(8);
                  
                   // 业务逻辑
         
               }
               //处理订阅事件 判断普通关注还是解锁关注
               message = MessageUtil.subscribeForText(toUserName, fromUserName, sceneStr);
            } else if(MessageUtil.MESSAGE_SCAN.equals(eventType)){
               // 添加扫码记录到datathink 下表中
               if(sceneStr.contains("-")){
                  String[] split = sceneStr.split("-");
                  // 业务逻辑
               }
               //处理扫码事件
               message = MessageUtil.scanForText(toUserName, fromUserName, sceneStr);

            } else if (MessageUtil.MESSAGE_UNSUBSCIBE.equals(eventType)) {
               //处理取消订阅事件
               message = MessageUtil.unsubscribe(toUserName, fromUserName);
            }
         }
         log.info("微信事件入参:" + JSON.toJSONString(map) + ", 微信事件返回信息:" + message);
         return message;
      } catch (DocumentException e) {
         log.error("checkSign===============" + e.getMessage());
      } finally {
//       out.println(message);
         /*if (out != null) {
            out.close();
         }*/
      }
      return null;
   }
工具类:
@Component
public class MessageUtil {
   /**
    * 消息类型--事件
    */
   public static final String MSGTYPE_EVENT = "event";
   /**
    * 消息事件类型--订阅事件
    */
   public static final String MESSAGE_SUBSCIBE = "subscribe";

   /**
    * 消息事件类型--扫描事件
    */
   public static final String MESSAGE_SCAN = "SCAN";
   /**
    * 消息事件类型--取消订阅事件
    */
   public static final String MESSAGE_UNSUBSCIBE = "unsubscribe";
   /**
    * 消息类型--文本消息
    */
   public static final String MESSAGE_TEXT = "text";

   @Autowired
   public ICompanyCdpClient cdpClient;
   public static ICompanyCdpClient companyCdpClient;
   @PostConstruct
   public void init() {
      companyCdpClient = cdpClient;
   }

   /**
    * 组装文本消息
    */
   public static String textMsg(String toUserName,String fromUserName,String content){
      TextMessage text = new TextMessage();
      text.setFromUserName(toUserName);
      text.setToUserName(fromUserName);
      text.setMsgType(MESSAGE_TEXT);
      text.setCreateTime(System.currentTimeMillis());
      text.setContent(content);
      return XmlUtil.textMsgToxml(text);
   }

   /**
    * 响应订阅事件--回复文本消息
    * @param toUserName
    * @param fromUserName
    * @param sceneStr userId-类型-公司名-国家
    * @return
    */
   public static String subscribeForText(String toUserName,String fromUserName, String sceneStr){
      if (StringUtils.isNotBlank(sceneStr) && sceneStr.contains("#")) {
         return textMsg(toUserName, fromUserName, "您已成功关注并绑定XXX账号,后续我们将不定期提醒买家更新及福利活动,有空记得多看看哦!");
      } else if (StringUtils.isNotBlank(sceneStr) && sceneStr.contains("-")) {
         // 解锁扫码关注
         return textMsg(toUserName, fromUserName, "/:rose感谢关注!\n" +
            "\n" +
            "企业信息挖掘成功后,我们将第一时间通知您。您也可以在关注该企业后,在个人中心-我的关注里查看相关进展");
      }
      return textMsg(toUserName, fromUserName, "感谢关注!\n" +
         "在公众号回复“热门买家”\n" +
         "/:rose将为您开通7天的免费试用!");
   }

   /**
    * 响应取消订阅事件
    */
   public static String unsubscribe(String toUserName,String fromUserName){
      //TODO 可以进行取关后的其他后续业务处理
      System.out.println("用户:"+ fromUserName +"取消关注~");
      return "";
   }
}
public class XmlUtil {
   /**
    * xml转map
    */
   public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException{
      HashMap<String, String> map = new HashMap<String,String>();
      SAXReader reader = new SAXReader();

      InputStream ins = request.getInputStream();
      Document doc = reader.read(ins);

      Element root = doc.getRootElement();
      @SuppressWarnings("unchecked")
      List<Element> list = (List<Element>)root.elements();

      for(Element e:list){
         map.put(e.getName(), e.getText());
      }
      ins.close();
      return map;
   }
   /**
    * 文本消息对象转xml
    */
   public static String textMsgToxml(TextMessage textMessage){
      XStream xstream = new XStream();
      xstream.alias("xml", textMessage.getClass());
      return xstream.toXML(textMessage);
   }
}
 
/**
 获取微信二维码: 该方法返回ticket 前端 可拿ticket请求获取二维码
**/
@Override
@PostMapping(value = "/getQrCode")
public BaseResponse getQrCode(@RequestBody UserScanReq userScanReq){
   BaseResponse baseResponse = new BaseResponse();
   org.springblade.core.tool.utils.ThreadLocalUtil.put("token", userScanReq.getToken());
   JResDTO dto = sysUserCenterInfoClient.getUserInfo();
   if (dto.getCode() != null && dto.getCode() == 0) {
      String accessToken = weChatService.getAccessToken(false);
      SysUserCenterInfoVO vo = (SysUserCenterInfoVO) dto.getData();
      ThreadLocalUtil.set(newUserKey, vo);

      Map<String, Object> map = new HashMap<>();
      map.put("expire_seconds", 86400);
      map.put("action_name", "QR_STR_SCENE");

      Map<String, Object> actionInfo = new HashMap<>();

      Map<String, String> sean = new HashMap<>();
      String sceneStr;
      if (userScanReq.getType() == 0) {
         // 个人中心二维码
         sceneStr = vo.getUserId();
      } else if(userScanReq.getType() == 1){
         sceneStr = vo.getUserId() + "#";
      }else{
         sceneStr = vo.getUserId() + "-" + userScanReq.getType() + "-" + userScanReq.getCompanyName() + "-" + userScanReq.getCountry();
      }
      sean.put("scene_str", sceneStr);

      actionInfo.put("scene", sean);
      map.put("action_info", actionInfo);

      // 1 获取ticket
      String result = HttpUtil.postJson(WxConstants.getQrcodeTicket + accessToken
         , JSON.toJSONString(map));

      JSONObject jsonObject = JSON.parseObject(result);

      log.info("wechat accessToken result : {}", result);
      if (jsonObject.containsKey("errcode")) {
         //重试 一次
          accessToken = weChatService.getAccessToken(true);
         // 1 获取ticket
          result = HttpUtil.postJson(WxConstants.getQrcodeTicket + accessToken
            , JSON.toJSONString(map));
         jsonObject = JSON.parseObject(result);
      }
      String ticket = jsonObject.getString("ticket");
      baseResponse.setData(ticket);
      success(baseResponse);
      return baseResponse;
   }
   baseResponse.setData("获取用户信息失败");
   error("获取用户信息失败", baseResponse);
   return baseResponse;
}
获取微信token:

public String getAccessToken(boolean refresh) {
        if (refresh || accessToken.isExpire()) {
            int count = 0;
            while (count < 5) {
				String result = HttpUtil.get(String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
					weChatAppId, weChatSecret));
                JSONObject resultJson = JSON.parseObject(result);
                logger.info("wechat accessToken result : {}", result);
                if (resultJson.containsKey("access_token")) {
                    accessToken.token = resultJson.getString("access_token");
                    accessToken.expiresIn = resultJson.getLong("expires_in");
                    accessToken.refreshTime = System.currentTimeMillis();
                } else if (resultJson.containsKey("errcode")) {
                    if (resultJson.getInteger("errcode") == -1) {
                        //重试
                        try {
                            Thread.sleep(count * 100L);
                        } catch (InterruptedException ignored) {
                        }
                        count++;
                        continue;

                    }
                }
                break;
            }
        }
        return accessToken.isExpire() ? null : accessToken.token;
    }
 
@Override
@ApiOperation(value = "获取用户是否关注公众号")
@PostMapping(value = "/getUserIsCollectedWX")
public BaseResponse<Boolean> getUserIsCollectedWX(@RequestBody TokenReq req){
   BaseResponse baseResponse = new BaseResponse();
   boolean flag = false;
   if (StringUtils.isBlank(req.getToken())) {
      baseResponse.setData(flag);
      success(baseResponse);
      return baseResponse;
   }
   org.springblade.core.tool.utils.ThreadLocalUtil.put("token", req.getToken());
   JResDTO dto = sysUserCenterInfoClient.getUserInfo();
   if (dto.getCode() != null && dto.getCode() == 0) {
      SysUserCenterInfoVO vo = (SysUserCenterInfoVO) dto.getData();
      if (StringUtils.isNotBlank(vo.getWxOpenId())) {
         try {
            WxUserInfoDto wxUserInfo = getWxUserInfoByOpenId(vo.getWxOpenId());
            if (StringUtils.isNotBlank(wxUserInfo.getSubscribe()) && StringUtils.equals(wxUserInfo.getSubscribe(), "1")) {
               flag = true;
            }
            log.info("微信获取用户基本信息返回参数:", wxUserInfo.toString());
         } catch (Exception e) {
            throw CommonException.createException("调用微信获取用户基本信息(UnionID机制)接口异常", e);
         }
      }
   }
   baseResponse.setData(flag);
   success(baseResponse);
   return baseResponse;
}
/**
	 * 根据用户微信openId获取微信信息
	 * @param openId
	 * @return
	 */
	private WxUserInfoDto getWxUserInfoByOpenId(String openId){
		String accessToken = weChatService.getAccessToken(false);
		String result = HttpUtil.get(String.format("https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN",
			accessToken, openId));
		WxUserInfoDto wxUserInfo = JSON.parseObject(result, WxUserInfoDto.class);
		return wxUserInfo;
	}


                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值