首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 微信開發實戰(二):接收訊息解析與被動回覆(文字/圖文/音樂/視頻)

     編輯:Java 相關知識

一、微信伺服器推送訊息流程

用戶發送 → 微信後台 → POST XML 到開發者 URL → 開發者解析 → 回覆 XML → 微信轉發給用戶
  • 請求方式:POST
  • 資料格式:XML(req.getInputStream() 讀取)
  • 回覆限制:5 秒內,超時微信會重試 3 次

二、接收訊息統一解析

@PostMapping("/wechat")
public void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception {
    req.setCharacterEncoding("UTF-8");
    resp.setCharacterEncoding("UTF-8");
    
    // 1. 讀取輸入流
    InputStream is = req.getInputStream();
    
    // 2. DOM4J 解析 XML 轉 Map
    SAXReader reader = new SAXReader();
    Document doc = reader.read(is);
    Element root = doc.getRootElement();
    
    Map<String, String> msgMap = new HashMap<>();
    for (Element e : root.elements()) {
        msgMap.put(e.getName(), e.getTextTrim());
    }
    
    // 3. 核心欄位
    String msgType = msgMap.get("MsgType");      // text, image, voice, video, event...
    String fromUser = msgMap.get("FromUserName");
    String toUser = msgMap.get("ToUserName");
    long createTime = System.currentTimeMillis();
    
    // 4. 根據類型分發處理
    String replyXml = buildReply(msgType, msgMap, fromUser, toUser, createTime);
    
    // 5. 輸出回覆
    resp.getWriter().write(replyXml);
}

三、回覆訊息構建:XStream Bean 轉 XML

依賴:com.thoughtworks.xstream:xstream:1.4.18

基礎實體類


// 文字訊息
@XStreamAlias("xml")
public class TextMsg {
    String ToUserName, FromUserName, CreateTime, MsgType, Content;
    // getter/setter
}

// 圖文訊息
@XStreamAlias("xml")
public class NewsMsg {
    String ToUserName, FromUserName, CreateTime, MsgType = "news";
    int ArticleCount;
    List<Article> Articles;
}

public class Article {
    String Title, Description, PicUrl, Url;
}

構建工具方法

private String toXml(Object msg) {
    XStream xstream = new XStream(new DomDriver("UTF-8", new NoNameCoder()));
    xstream.processAnnotations(msg.getClass());
    // 子元素別名
    if (msg instanceof NewsMsg) xstream.alias("item", Article.class);
    return xstream.toXML(msg);
}

四、各類型回覆實戰

1. 文字訊息

TextMsg text = new TextMsg();
text.setToUserName(fromUser);
text.setFromUserName(toUser);
text.setCreateTime(createTime);
text.setMsgType("text");
text.setContent("收到:" + msgMap.get("Content"));
return toXml(text);

2. 圖文訊息

List<Article> articles = new ArrayList<>();
Article a = new Article();
a.setTitle("SpringBoot 實戰");
a.setDescription("從入門到精通");
a.setPicUrl("https://example.com/cover.jpg");
a.setUrl("https://example.com/detail");
articles.add(a);

NewsMsg news = new NewsMsg();
news.setToUserName(fromUser);
news.setFromUserName(toUser);
news.setCreateTime(createTime);
news.setArticleCount(articles.size());
news.setArticles(articles);
return toXml(news);

3. 圖片/語音/視頻訊息(需先上傳素材獲取 MediaId)

// 圖片
ImageMsg img = new ImageMsg();
img.setToUserName(fromUser);
img.setFromUserName(toUser);
img.setCreateTime(createTime);
img.setMsgType("image");
img.setMediaId(mediaId); // 素材管理介面上傳獲得
return toXml(img);

五、事件推送處理

Event場景關鍵欄位
subscribe關注公眾號EventKey (qrscene_ 開頭為帶參數二維碼)
unsubscribe取消關注無法回覆
CLICK自訂選單點擊EventKey (選單 key)
VIEW跳轉鏈接無回覆
SCAN掃帶參數二維碼EventKey, Ticket
LOCATION上報地理位置Latitude, Longitude, Precision

六、加密模式(安全模式/兼容模式)

  • 驗證簽名:SHA1(sort(token, timestamp, nonce)) == signature
  • 解密請求:AES 解密 Encrypt 欄位
  • 加密回覆:AES 加密 XML → 包裝 Encrypt、MsgSignature、TimeStamp、Nonce
  • 建議使用 weixin-java-mp / WxMpService 封裝庫自動處理

七、完整 Servlet 範例(含驗證、解析、回覆)

@WebServlet("/wechat")
public class WechatServlet extends HttpServlet {
    private static final String TOKEN = "your_token";
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        // 驗證簽名
        String signature = req.getParameter("signature");
        String timestamp = req.getParameter("timestamp");
        String nonce = req.getParameter("nonce");
        String echostr = req.getParameter("echostr");
        
        String[] arr = {TOKEN, timestamp, nonce};
        Arrays.sort(arr);
        String sha1 = SHA1Util.encode(String.join("", arr));
        
        if (sha1.equals(signature)) resp.getWriter().print(echostr);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        // 解析、構建回覆、輸出(同上邏輯)
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved