处理与回复消息--微信公众平台开发(五)

论坛 期权论坛 脚本     
匿名技术用户   2021-1-2 00:27   94   0

接收到公众号发来的消息后的流程是(个人意见):

step 1:将xml格式的消息转化为对象。

step 2:让消息进消息网关,按消息类型作分发。

step 3:如果消息为事件,则进入事件网关,按事件类型进行分发,非事件则无此步骤。

step 4:根据消息进行业务处理

step 5:若需要回复消息,则发送xml格式的消息给公众号用户。

Controller层代码:

 /**
  * 接收及回复微信消息
  * 
  * @param token
  * @param signature
  * @param timestamp
  * @param nonce
  * @param echostr
  * @param request
  * @param response
  * @return
  * @throws ServletException
  * @throws IOException
  */
 @RequestMapping("ansy/weixinMessage")
  @ResponseBody  
 public Callable<Object> weixinMessage(String token, String signature, String timestamp, String nonce,
   String echostr, HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {
  return new Callable<Object>() {
   OutData out = new OutData();
   public Object call() throws Exception {
    if (request.getMethod().toLowerCase().equals("get")) {
     doGet(signature, timestamp, nonce, echostr, response);
    } else {
     doPost(request, response);
    }
    out.setCode(1);
    out.setData(null);
    out.setMsg("success");
    return out;
   }
  };

 }

 /**
  * get方式验证token
  */
 public void doGet(String signature, String timestamp, String nonce, String echostr, HttpServletResponse response) {
  //第一个值是服务器配置的token,我们自定义的,和微信的access_token无关
  String[] ArrTmp = { "liboyi921216liboyisdfsdfsdfsdf", timestamp, nonce };
  Arrays.sort(ArrTmp);
  StringBuffer sb = new StringBuffer();
  for (int i = 0; i < ArrTmp.length; i++) {
   sb.append(ArrTmp[i]);
  }
  String pwd = WeixinMessageDigestUtil.getInstance().encipher(sb.toString());
  if (pwd.equals(signature)) {
   if (!"".equals(echostr) && echostr != null) {
    try {
     PrintWriter writer = response.getWriter();
     writer.print(echostr);
     writer.flush();
     writer.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }
 }

 /**
  * 处理微信服务器发来的消息
  */
 public void doPost(HttpServletRequest request, HttpServletResponse response) throws Exception {
  // 将请求、响应的编码均设置为UTF-8(防止中文乱码)
  request.setCharacterEncoding("UTF-8");
  response.setCharacterEncoding("UTF-8");
  // 调用核心业务类接收消息、处理消息
  String respMessage = coreService.processRequest(request);
  // 响应消息
  PrintWriter out = response.getWriter();
  out.print(respMessage);
  out.flush();
  out.close();
 }
Service层代码:

 /**
  * 处理微信发来的请求
  * 
  * @param request
  * @return
  * @throws Exception 
  */
 public String processRequest(HttpServletRequest request) throws Exception {
  // xml请求解析
  Map<String, String> requestMap = WeixinMessageUtil.parseXml(request);
  // 消息类型
  String msgType = requestMap.get("MsgType");
  // 回复消息
  return msgGateWay(msgType, requestMap);
 }
       /**
     * 获取微信公众号平台接口的ACCESS_TOKEN
     * @return
     */
    public  String getWeixinAccessToken(){
        WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
        ServletContext application = webApplicationContext.getServletContext();
        if(application.getAttribute("tokenMap")!=null){
            WeixinAccessToken tempToken=(WeixinAccessToken) application.getAttribute("tokenMap");
            if(System.currentTimeMillis()>tempToken.getExpirationTime()){
                return tempToken.getAccessToken();
            }else{
                return getAccessToken();
            }
        }else{
            return getAccessToken();
        }
    }

    private String getAccessToken() {
        WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
        ServletContext application = webApplicationContext.getServletContext();
        String appId=appid;
        String appSecret=secret;
        String url="https://api.weixin.qq.com/cgi-bin/token";
        String returnData=Common.sendGet(url,"grant_type=client_credential&appid="+appId+"&secret="+appSecret);
        JSONObject json=JSONObject.fromObject(returnData);
        if(json.containsKey("access_token")){
            if(json.get("access_token")!=null&&!json.get("access_token").equals("")){
                application.setAttribute("tokenMap", new WeixinAccessToken(json.get("access_token").toString(),
                        System.currentTimeMillis()+Integer.parseInt(json.get("expires_in").toString())));
                return json.get("access_token").toString();
            }
        }
        return null;
    } 
     /**
     * 消息网关
     * @param msgType
     * @throws Exception 
     */
    private String msgGateWay(String msgType,Map<String, String> requestMap) throws Exception {
        String toUserName=requestMap.get("ToUserName");
        String fromUserName=requestMap.get("FromUserName");
        String initMsg="Hi,我是美少女小冷。我还处于成长阶段,目前不能理解你说了什么。呜呜呜……";
        WeixinMessageXmlUtil messageUtil=null;
        String responseMsg="";
        if (msgType.equals(WeixinMsgType.text.toString())) { // 文本消息
            messageUtil=new  WeixinMessageXmlUtil(fromUserName,toUserName,System.currentTimeMillis(),
                    WeixinMsgType.text.toString(),initMsg);
             responseMsg= WeixinMessageXmlUtil.objectToXml(messageUtil);
        }else if (msgType.equals(WeixinMsgType.image.toString())) { // 图片消息

        }else if (msgType.equals(WeixinMsgType.voice.toString())) { // 语音消息

        }else if (msgType.equals(WeixinMsgType.video.toString())) {// 视频消息

        }else if (msgType.equals(WeixinMsgType.shortvideo.toString())) { // 小视频消息

        }else if (msgType.equals(WeixinMsgType.location.toString())) { // 地理位置消息

        }else if (msgType.equals(WeixinMsgType.link.toString())) {  // 链接消息

        }else if (msgType.equals(WeixinMsgType.music.toString())) { // 音乐消息

        }else if (msgType.equals(WeixinMsgType.news.toString())) { // 图文消息

        }else if (msgType.equals(WeixinMsgType.event.toString())) { // 事件消息
            String eventType = requestMap.get("Event");
            if(eventType!=null&&!eventType.equals("")){
                return eventGateWay(eventType,requestMap);
            }
        }
        
         return responseMsg;
    }
    
    /**
     * 事件网关
     * @param eventType
     * @throws Exception 
     */
    private String eventGateWay(String eventType, Map<String, String> requestMap) throws Exception {
        if (eventType == null || requestMap == null) {
            return null;
        }
        // 发送方帐号(open_id)
        String fromUserName = requestMap.get("FromUserName");
        // 公众帐号
        String toUserName = requestMap.get("ToUserName");
        if (eventType.equals(WeixinEventType.subscribe.toString())) { // 关注
            if (requestMap.containsKey("EventKey")) {
                if (!requestMap.get("EventKey").equals("") && requestMap.get("EventKey") != null) {
                    // 拿到参数(用户id)
                    String userId = requestMap.get("EventKey").substring(8);
                    WeixinUserInfo userWeixinInfo=getWeixinUserInfoByOpenId(fromUserName); 
                    if(userWeixinInfo==null){
                        userWeixinInfo=new WeixinUserInfo();
                    }
                    //业务处理代码
                }
            }
            String loginUrl="https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxe91c058fd370ab41&redirect_uri=http://www.coldle.com/weike/"
                    + "api/wxuser/ansy/getAccessToken.shtml?iswebchat=1&response_type=code&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect ";
            StringBuffer msgContent=new StringBuffer();
            msgContent.append("Coldle冷暖在线欢迎您\n");
            msgContent.append("冷暖在线是服务于制冷、空调、暖通专业的第三方平台,涉及的方面如下:\n");
            msgContent.append("1、项目的方案、设计及施工的发布与承接。\n");
            msgContent.append("2、设备、阀件的采购和团购。\n");
            msgContent.append("3、项目运营物业管理与远程维保。\n");
            msgContent.append("4、项目的招标与投标信息发布。\n");
            msgContent.append("5、冷库、冷藏车的出租与承租。\n");
            msgContent.append("6、专业人才的求职与招聘。\n");
            msgContent.append("7、专业资料查询及疑难问题的咨询。\n");
            msgContent.append("<a href=\""+loginUrl+"\">登录注册</a>冷暖在线官网http://www.coldle.com了解更多。\n");
//            String msgContent = "感谢您关注蝌蚪冷暖在线公众号!";
            String msgXml = WeixinMessageXmlUtil.objectToXml(new WeixinMessageXmlUtil(fromUserName, toUserName,
                    System.currentTimeMillis(), WeixinMsgType.text.toString(), msgContent.toString()));
            return msgXml;
        } else if (eventType.equals(WeixinEventType.unsubscribe.toString())) { // 取消关注

        } else if (eventType.equals(WeixinEventType.SCAN.toString())) { // 扫码

        } else if (eventType.equals(WeixinEventType.LOCATION.toString())) {// 上报地理位置信息

        } else if (eventType.equals(WeixinEventType.CLICK.toString())) {// 自定义菜单点击

        }
        return "success";
    }

WeixinMessageXmlUtil将文字消息转为xml:

package com.exp.util;

import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "xml") 
public class WeixinMessageXmlUtil {
 private String ToUserName;  //接收方帐号(收到的OpenID)
 private String FromUserName; //开发者微信号
 private long CreateTime;     //创建时间
 private String MsgType;       //消息类型
 private String Content;             //内容
 
 
 public WeixinMessageXmlUtil(){
  
 }
 public WeixinMessageXmlUtil(String ToUserName,String FromUserName,long CreateTime,String MsgType,String Content){
  this.ToUserName=ToUserName;
  this.FromUserName=FromUserName;
  this.CreateTime=CreateTime;
  this.MsgType=MsgType;
  this.Content=Content;
 }
 
 /**
  * 对象转为xml格式
  * @param tx
  * @return
  * @throws Exception 
  */
 public static String objectToXml(WeixinMessageXmlUtil tx) throws Exception{
     StringWriter sw = new StringWriter();  
        JAXBContext jbc=JAXBContext.newInstance(tx.getClass());   //传入要转换成xml的对象类型  
        Marshaller marshaller = jbc.createMarshaller();  
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");// //编码格式
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);// 是否格式化生成的xml串
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);// 是否省略xm头声明信息
        marshaller.marshal(tx, sw);  
        String msg=sw.toString();
        msg= msg.replace("content", "Content");
        msg= msg.replace("createTime", "CreateTime");
        msg= msg.replace("fromUserName", "FromUserName");
        msg= msg.replace("msgType", "MsgType");
        msg= msg.replace("toUserName", "ToUserName");
  return msg;
 }
 
 
  public String getToUserName() {
  return ToUserName;
 }

 public void setToUserName(String toUserName) {
  ToUserName = toUserName;
 }

 public String getFromUserName() {
  return FromUserName;
 }

 public void setFromUserName(String fromUserName) {
  FromUserName = fromUserName;
 }

 public long getCreateTime() {
  return CreateTime;
 }

 public void setCreateTime(long createTime) {
  CreateTime = createTime;
 }

 
 public String getMsgType() {
  return MsgType;
 }
 public void setMsgType(String msgType) {
  MsgType = msgType;
 }
 public String getContent() {
  return Content;
 }
 public void setContent(String content) {
  Content = content;
 }
 public static void main(String[] args){  
      WeixinMessageXmlUtil tx =new WeixinMessageXmlUtil("111111", "2222222", 21312321, "test","呵呵");
      String xmlMsg="";
   try {
    xmlMsg = tx.objectToXml(tx);
   } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
         System.out.println(xmlMsg);  
 }  
}
注:微信端需要的xml格式,不需要xml声明头,并且属性名需要首字母大写。
格式要严格匹配,否则消息发送不成功。


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP