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

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

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声明头,并且属性名需要首字母大写。
格式要严格匹配,否则消息发送不成功。

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李秀才

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值