手把手微信開發之WeixinUrlFilter完整源碼

可能是大家對我前面的文章看得不是很清楚,再者我在載錄的時候,有個別錯誤

所以我現在直接將整個代碼完整的發一遍:

com.ansitech.weixin.sdk.WeixinUrlFilter.java

package com.ansitech.weixin.sdk;

import com.ansitech.weixin.sdk.message.InputMessage;
import com.ansitech.weixin.sdk.message.MsgType;
import com.ansitech.weixin.sdk.message.OutputMessage;
import com.ansitech.weixin.sdk.message.TextOutputMessage;
import com.ansitech.weixin.sdk.util.SHA1;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class WeixinUrlFilter implements Filter {

    //這個Token是給微信開發者接入時填的  
    //可以是任意英文字母或數字,長度爲3-32字符  
    private static String Token = "vzhanqun1234567890";

    @Override
    public void init(FilterConfig config) throws ServletException {
        System.out.println("WeixinUrlFilter啓動成功!");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        //微信服務器將發送GET請求到填寫的URL上,這裏需要判定是否爲GET請求  
        boolean isGet = request.getMethod().toLowerCase().equals("get");
        System.out.println("獲得微信請求:" + request.getMethod() + " 方式");
        if (isGet) {
            //驗證URL真實性  
            String signature = request.getParameter("signature");// 微信加密簽名  
            String timestamp = request.getParameter("timestamp");// 時間戳  
            String nonce = request.getParameter("nonce");// 隨機數  
            String echostr = request.getParameter("echostr");//隨機字符串  
            List<String> params = new ArrayList<String>();
            params.add(Token);
            params.add(timestamp);
            params.add(nonce);
            //1. 將token、timestamp、nonce三個參數進行字典序排序  
            Collections.sort(params, new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    return o1.compareTo(o2);
                }
            });
            //2. 將三個參數字符串拼接成一個字符串進行sha1加密  
            String temp = SHA1.encode(params.get(0) + params.get(1) + params.get(2));
            if (temp.equals(signature)) {
                response.getWriter().write(echostr);
            }
        } else {
            //處理接收消息  
            ServletInputStream in = request.getInputStream();
            //將POST流轉換爲XStream對象
            XStream xs = new XStream(new DomDriver());
            //將指定節點下的xml節點數據映射爲對象
            xs.alias("xml", InputMessage.class);
            //將流轉換爲字符串
            StringBuilder xmlMsg = new StringBuilder();
            byte[] b = new byte[4096];
            for (int n; (n = in.read(b)) != -1;) {
                xmlMsg.append(new String(b, 0, n, "UTF-8"));
            }
            //將xml內容轉換爲InputMessage對象
            InputMessage inputMsg = (InputMessage) xs.fromXML(xmlMsg.toString());
            // 取得消息類型
            String msgType = inputMsg.getMsgType();
            //根據消息類型獲取對應的消息內容
            if (msgType.equals(MsgType.Text.toString())) {
                try {
                    //文本消息
                    System.out.println("開發者微信號:" + inputMsg.getToUserName());
                    System.out.println("發送方帳號:" + inputMsg.getFromUserName());
                    System.out.println("消息創建時間:" + inputMsg.getCreateTime());
                    System.out.println("消息內容:" + inputMsg.getContent());
                    System.out.println("消息Id:" + inputMsg.getMsgId());
                    //發送文本消息 start
                    XStream xstream = new XStream(new XppDriver() {
                        @Override
                        public HierarchicalStreamWriter createWriter(Writer out) {
                            return new PrettyPrintWriter(out) {
                                @Override
                                protected void writeText(QuickWriter writer, String text) {
                                    if (!text.startsWith("<![CDATA[")) {
                                        text = "<![CDATA[" + text + "]]>";
                                    }
                                    writer.write(text);
                                }
                            };
                        }
                    });
                    //創建文本發送消息對象
                    TextOutputMessage outputMsg = new TextOutputMessage();
                    outputMsg.setContent("你的消息已經收到,謝謝!");
                    setOutputMsgInfo(outputMsg, inputMsg);
                    //設置對象轉換的XML根節點爲xml
                    xs.alias("xml", outputMsg.getClass());
                    //將對象轉換爲XML字符串
                    String xml = xstream.toXML(outputMsg);
                    //將內容發送給微信服務器,發送到用戶手機
                    response.getWriter().write(xml);
                } catch (Exception ex) {
                    System.out.println("消息接受和發送出現異常!");
                    ex.printStackTrace();
                }
            }
        }
    }

    //設置詳細信息
    private static void setOutputMsgInfo(OutputMessage oms, InputMessage msg) throws Exception {
        // 設置發送信息
        Class<?> outMsg = oms.getClass().getSuperclass();
        Field CreateTime = outMsg.getDeclaredField("CreateTime");
        Field ToUserName = outMsg.getDeclaredField("ToUserName");
        Field FromUserName = outMsg.getDeclaredField("FromUserName");

        ToUserName.setAccessible(true);
        CreateTime.setAccessible(true);
        FromUserName.setAccessible(true);

        CreateTime.set(oms, new Date().getTime());
        ToUserName.set(oms, msg.getFromUserName());
        FromUserName.set(oms, msg.getToUserName());
    }

    @Override
    public void destroy() {
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章