1. 程式人生 > >最簡單web工程接收訊息圖片--微信企業號

最簡單web工程接收訊息圖片--微信企業號

java的web 工程,接收訊息,傳送圖片資訊

企業微信api
企業號開發者介面文件
企業微信介面除錯工具
微信企業號錯誤程式碼查詢工具
原理:有移動端輸入資訊到企業號,企業號中的資訊有微信伺服器加密之後傳送給自己的服務,自己的服務接收到資訊、解密、獲取資訊、處理資訊,加密、返回資訊給微信伺服器,後顯示到企業號中;
但是因為這種需要在5s內相應,否則視為相應失敗;
所以我們是有api文件建議的類似於非同步傳送,自己的服務接收處理資訊後,直接返回200,給微信伺服器標示為處理成功,之後在呼叫主動傳送訊息,傳送給特定的使用者;
整個專案war-好多資訊懶得改

程式碼案例

其中get請求處理url驗證,post請求處理移動端主動傳送的資訊及回覆;
傳送圖片,呼叫主動傳送的資訊
其中加密解密都有參考可看,主動傳送的例項都在test資料夾中,util資料夾是各種工具類;

(可參考前幾篇相關文章)

package servlet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import net.sf.json.JSONObject;
import util.AesException;
import util.MediaUploadUtil;
import util.WXBizMsgCrypt;
import util.WxworkNewsType;
import util.WxworkUtil;

/**
 * @version 本servlet,針對微信企業號,其中get處理url校驗,post處理接收資訊處理
 * @author pwu
 * @time 20180201
 */

public class ResponseNews extends HttpServlet {

    // 設定企業號後臺引數
    static String sToken = "QDG6eK";
    static String sEncodingAESKey = "jWmYm7qr5nMoAUwZRjGtBxmz3KA1tkAj3ykkR6q2B2C";
    static String sCorpID = "ww248ac59c619621da";
    static String sAgentId = "1000002";
    static String corpsecret = "uXWrHT-Kxjttu1nDga-fdKqs6SCi01cq-nVb4bfXsSE";
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {

        PrintWriter out = response.getWriter();
        SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
        // System.out.println("request-url:" +
        // request.getRequestURL().toString());
        System.out.println("ResponseNews----get--" + sFormat.format(new Date()));

        // System.out.println("請求格式:" + request.getContentType());
        request.setCharacterEncoding("utf-8");
        // String getContextPath = request.getContextPath();
        // String basePath = request.getScheme() + "://" +
        // request.getServerName() + ":" + request.getServerPort()
        // + getContextPath + "/";
        // System.out.println("basePath:" + basePath);
        /*
         * String getRemoteAddress=request.getRemoteAddr(); String
         * getServletPath =request.getServletPath(); String
         * getServletContext_getRealPath =request.getServletPath();
         */
        // String getRequestURL = request.getRequestURL().toString();
        // System.out.println("getRequestURL:" + getRequestURL);
        /*
         * String getRequestURI =request.getRequestURI(); String getRemoteUser
         * =request.getRemoteUser();
         */
        String getQueryString = request.getQueryString();
        if (request.getQueryString() == null || ("").equals(request.getQueryString())) {
            out.println("request no querystring");
        } else {
            System.out.println("getQueryString:" + getQueryString);
            // System.out.println("請求引數getQueryString:" + getQueryString);

            // System.out.println("需要解密的欄位,獲取其中echostr資訊:"+teMap.get("echostr"));
            // System.out.println("request.getParameter--" +
            // request.getParameter("echostr"));
            String sVerifyMsgSig = request.getParameter("msg_signature");
            String sVerifyTimeStamp = request.getParameter("timestamp");
            String sVerifyNonce = request.getParameter("nonce");
            String sVerifyEchoStr = request.getParameter("echostr");

            String sEchoStr = null; // 需要返回的明文
            WXBizMsgCrypt wxcpt = null;

            if (sEncodingAESKey.length() != 43) {
                System.out.println("sEncodingAESKey 長度異常");
            }

            try {
                wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
                sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp, sVerifyNonce, sVerifyEchoStr);
                System.out.println("解密結果verifyurl echostr: " + sEchoStr);
                // 驗證URL成功,將sEchoStr返回
            } catch (Exception e) {
                // 驗證URL失敗,錯誤原因請檢視異常
                e.printStackTrace();
            }

            /*
             * response.setCharacterEncoding("UTF-8");//設定將字元以"UTF-8"編碼輸出到客戶端瀏覽器
             * response.setHeader("content-type", "text/html;charset=UTF-8");
             * response.setContentType("text/htmll;charset=utf-8");
             */

            String numbers = sEchoStr;
            out.println(numbers);
        }
    }

    /**
     * The doPost method of the servlet. <br
>
* * This method is called when a form has its tag value method equals to * post. * * @param request * the request send by the client to the server * @param response * the response send by the server to the client * @throws ServletException * if an error occurred * @throws IOException * if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { long time1 = System.currentTimeMillis(); // 獲取accestoken後,傳送post請求,目前傳送txt格式,傳送的引數為json格式 JSONObject jsparam = new JSONObject(); JSONObject jsparam2 = new JSONObject(); WXBizMsgCrypt wxcpt = null; String sReqMsgSig = null;// String sReqTimeStamp = null;// 時間戳 String sReqNonce = null;// 隨機數 // 解密訊息引數 String ToUserName = null;// 傳送資訊使用者名稱 String MsgId = null;// 此次訊息的msgid String Content = null;// 請求訊息 try { wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID); } catch (AesException e1) { e1.printStackTrace(); } System.out.println("處理Post()請求------"); System.out.println("*************************request資訊如下:**************"); response.setContentType("text/html;charset=UTF-8"); /* * String getContextPath = request.getContextPath(); String basePath = * request.getScheme()+"://"+request.getServerName()+":"+request. * getServerPort()+getContextPath+"/"; String getServletPath = * request.getServletPath(); String getRemoteUser = * request.getRemoteUser(); String getRequestUri = * request.getRequestURI(); */ String getRequestUrl = request.getRequestURL().toString(); String getQueryString = request.getQueryString(); // 獲取請求體 BufferedReader bReader = request.getReader(); String str, sReqData = ""; while ((str = bReader.readLine()) != null) { sReqData += str; } // System.out.println("getContextPath:"+getContextPath); // System.out.println("basePath:"+basePath); System.out.println("getRequestUrl:" + getRequestUrl); // System.out.println("getRequestUri:"+getRequestUri); // System.out.println("getQueryString:" + getQueryString); System.out.println("請求body的加密資訊:" + sReqData); // 對url中的引數進行校驗和處理 if (getQueryString == null && ("").equals(getQueryString)) { System.out.println("請求url的引數為空"); } // System.out.println("獲取url引數後,需要解密"); sReqMsgSig = request.getParameter("msg_signature"); sReqTimeStamp = request.getParameter("timestamp"); sReqNonce = request.getParameter("nonce"); String sMsg = ""; try { sMsg = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData); System.out.println("解密結果after decrypt msg: " + sMsg); // TODO: 解析出明文xml標籤的內容進行處理 // For example: DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); StringReader sr = new StringReader(sMsg); InputSource is = new InputSource(sr); Document document = db.parse(is); Element root = document.getDocumentElement(); NodeList nodelist1 = root.getElementsByTagName("Content"); Content = nodelist1.item(0).getTextContent(); ToUserName = root.getElementsByTagName("AgentID").item(0).getTextContent(); MsgId = root.getElementsByTagName("MsgId").item(0).getTextContent(); System.out.println("解析企業號傳送資訊Content:" + Content); } catch (AesException e) { System.out.println("獲取request引數及body後,解析異常"); e.printStackTrace(); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("*************************response資訊入下:****************"); response.setContentType("text/htmll;charset=utf-8"); /* * 處理返回的加密資訊 其中xml中的Nonce是隨機數,TimeStamp是時間戳 sReqTimeStamp, * sReqNonce取自請求request引數 * */ PrintWriter out = response.getWriter(); // String sRespData = // "<xml
>
<ToUserName><![CDATA[mycreate]]></ToUserName><FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this // is a // test]]></Content><MsgId>1234567890123456</MsgId><AgentID>128</AgentID></xml>"; // String sRespData = // "<xml><ToUserName><![CDATA[PengWu]]></ToUserName><FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this // is a // test]]></Content><MsgId>1234567890123456</MsgId><AgentID>1000002</AgentID></xml>"; String sRespData = ""; if (("text1").equals(Content)) { sRespData = "<xml><ToUserName><![CDATA[" + ToUserName + "]]></ToUserName><FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName><CreateTime>" + System.currentTimeMillis() + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + "response news -- test,type:text" + "]]></Content><MsgId>" + MsgId + "</MsgId><AgentID>" + sAgentId + "</AgentID></xml>"; } else if (("text2").equals(Content)) { sRespData = "200"; /**使用非同步傳送 * 1.獲取access_token,在傳送文字資訊,呼叫工具 */ String access_token = WxworkUtil.GetForAT(sCorpID, corpsecret).get("access_token"); JSONObject jObject = WxworkNewsType.textType("文字資訊,非同步傳送", ToUserName, "", sAgentId); String result = WxworkUtil.sendData(access_token, jObject).get("errmsg"); System.out.println("返回傳送結果errmsg:"+result); } else if (("image").equals(Content)) { /* * String access_token = WxworkUtil.GetForAT(sCorpID, * corpsecret).get("access_token"); * System.out.println("accest_token:"+access_token); String mediaid * = MediaUploadUtil.uploadMedia(access_token, "image", * "http://pic.sc.chinaz.com/files/pic/pic9/201801/zzpic9711.jpg"); * String media_id = WxworkUtil.readRuslt(mediaid).get("media_id"); * System.out.println("media_id:"+media_id); sRespData = * "<xml><ToUserName><![CDATA["+ ToUserName * +"]]></ToUserName><FromUserName><![CDATA["+ sCorpID * +"]]></FromUserName><CreateTime>"+ System.currentTimeMillis() * +"</CreateTime><MsgType><![CDATA["+ "image" * +"]]></MsgType><PicUrl><![CDATA["+ * "http://pic.sc.chinaz.com/files/pic/pic9/201801/zzpic9711.jpg" * +"]]></PicUrl><MediaId><![CDATA[" + media_id + * "]]></MediaId><MsgId>"+ MsgId +"</MsgId><AgentID>"+ sAgentId * +"</AgentID></xml>"; */ sRespData = "200"; /** * 在這裡呼叫主動傳送資訊,傳送除了文字資訊之外的資料 */ String access_token = WxworkUtil.GetForAT(sCorpID, corpsecret).get("access_token"); String result = MediaUploadUtil.uploadMedia(access_token, "image", "http://pic.sc.chinaz.com/files/pic/pic9/201801/zzpic9711.jpg"); System.out.println("result---media_id:" + result); jsparam.put("media_id", WxworkUtil.readRuslt(result).get("media_id")); jsparam2.put("image", jsparam); jsparam2.put("msgtype", "image"); jsparam2.put("agentid", 1000002); jsparam2.put("touser", "PengWu"); jsparam2.put("safe", "0"); String sendruslt = WxworkUtil.sendData(access_token, jsparam2).get("errmsg"); System.out.println("post請求返回結果:" + sendruslt); } else if (("link").equals(Content)) { sRespData = "<xml><ToUserName><![CDATA[" + sCorpID + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + System.currentTimeMillis() + "</CreateTime><MsgType><![CDATA[" + "link" + "]]></MsgType><Title><![CDATA[" + "this is a title!--test link" + "]]></Title><Description><![CDATA[" + "this is a description!--test link" + "]]></Description><PicUrl><![CDATA[" + "http://pic.sc.chinaz.com/files/pic/pic9/201801/zzpic9711.jpg" + "]]></PicUrl><MsgId>" + MsgId + "</MsgId><AgentID>" + sAgentId + "</AgentID></xml>"; } else { sRespData = "<xml><ToUserName><![CDATA[" + ToUserName + "]]></ToUserName><FromUserName><![CDATA[" + sCorpID + "]]></FromUserName><CreateTime>" + System.currentTimeMillis() + "</CreateTime><MsgType><![CDATA[" + "text" + "]]></MsgType><Content><![CDATA[" + Content + "]]></Content><MsgId>" + MsgId + "</MsgId><AgentID>" + sAgentId + "</AgentID></xml>"; } // String sRespData = ToXmlString("response news -- test ",ToUserName); try { String sEncryptMsg = wxcpt.EncryptMsg(sRespData, sReqTimeStamp, sReqNonce); System.out.println("相應訊息加密結果--after encrypt sEncrytMsg: " + sEncryptMsg); out.println(sEncryptMsg); long time2 = System.currentTimeMillis() - time1; System.out.println("限制為5000,服務端處理資訊的時間-->" + time2); // 加密成功 // TODO: // HttpUtils.SetResponse(sEncryptMsg); } catch (Exception e) { e.printStackTrace(); // 加密失敗 } } // 對於txt格式的xml生成 private String ToXmlString(String content, String ToUserName) { Random random = new Random(); // "<xml><ToUserName><![CDATA[mycreate]]></ToUserName><FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this // is a // test]]></Content><MsgId>1234567890123456</MsgId><AgentID>128</AgentID></xml>"; String lString = "<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime><MsgType><![CDATA[{3}]]></MsgType><Content><![CDATA[{4}]]></Content><MsgId>{5}</MsgId><AgentID>{6}</AgentID></xml>"; lString = String.format(lString, ToUserName, sCorpID, System.currentTimeMillis(), "text", content, random.nextInt(214748364) + 1, sAgentId); // String s = // "<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime><MsgType><![CDATA[{3}]]></MsgType><Content><![CDATA[{4}]]></Content></xml>"; // s = String.format(s,"wzwl005", sCorpID, System.currentTimeMillis(), // "text", content); return lString; } }

效果圖:
這裡寫圖片描述
將其中個個常用的方法的抽離類(不知道對不對,還沒測完):

package util;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * @version 整理常用到的訊息型別,抽離成固定方法,需要時直接呼叫;
 * @author pwu
 *
 */
public class WxworkNewsType {

    static JSONObject jb = new JSONObject();
    static JSONObject jb1 = new JSONObject();
    static JSONObject jb2 = new JSONObject();
    /**@description 文字資訊格式,主動傳送
     * @param
     *  例子:
     * {
       "touser" : "UserID1|UserID2|UserID3",
       "toparty" : "PartyID1|PartyID2",
       "totag" : "TagID1 | TagID2",
       "msgtype" : "text",
       "agentid" : 1,
       "text" : {
           "content" : "你的快遞已到,請攜帶工卡前往郵件中心領取。\n出發前可檢視<a href=\"http://work.weixin.qq.com\">郵件中心視訊實況</a>,聰明避開排隊。"
       },
       "safe":0
    }
     */
    public static JSONObject textType(String content,String touser,String toparty,String agentid){
        jb1.put("content", content);
        jb.put("text", jb1);
        jb.put("msgtype" , "text");
        jb.put("safe" , 0);
        jb.put("agentid", agentid);
        if (touser != null ) {
            jb.put("touser", touser);
        }else {
            System.out.println("文字訊息引數不規範,將會發送給所有人!");
            jb.put("touser", "@all");
        }
        if (toparty != null) {
            jb.put("toparty", toparty);
        }
        return jb;
    }
    /**
     * @description 圖文資訊格式,主動傳送
     * @param
         {
       "touser" : "UserID1|UserID2|UserID3",
       "toparty" : "PartyID1 | PartyID2",
       "totag" : "TagID1 | TagID2",
       "msgtype" : "news",
       "agentid" : 1,
       "news" : {
           "articles" : [
               {
                   "title" : "中秋節禮品領取",
                   "description" : "今年中秋節公司有豪禮相送",
                   "url" : "URL",
                   "picurl" : "http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png",
                   "btntxt":"更多"
               }
            ]
       }
    }
     */
    public static JSONObject newsType(String touser,String toparty,String agentid,String title,
            String description,String url,String picurl,String btntxt){
        jb2.put("btntxt", btntxt);
        jb2.put("picurl", picurl);
        jb2.put("url", url);
        jb2.put("description", description);
        jb2.put("title", title);
        JSONArray articles = new JSONArray();
        articles.add(jb1);
        jb1.put("articles", articles);
        jb.put("news", jb1);
        jb.put("msgtype" , "news");
        jb.put("agentid", agentid);

        if (touser != null ) {
            jb.put("touser", touser);
        }else {
            System.out.println("文字訊息引數不規範,將會發送給所有人!");
            jb.put("touser", "@all");
        }
        if (toparty != null) {
            jb.put("toparty", toparty);
        }
        return jb;
    }
    /**
     * @description 圖片資訊格式,主動傳送
     * @param 
     *     {
       "touser" : "UserID1|UserID2|UserID3",
       "toparty" : "PartyID1|PartyID2",
       "totag" : "TagID1 | TagID2",
       "msgtype" : "image",
       "agentid" : 1,
       "image" : {
            "media_id" : "MEDIA_ID"
       },
       "safe":0
    }
     */
    public static JSONObject imageType(String media_id,String touser,String toparty,String agentid){
        jb1.put("media_id", media_id);
        jb.put("image", jb1);
        jb.put("msgtype" , "image");
        jb.put("safe" , 0);
        jb.put("agentid", agentid);
        if (touser != null ) {
            jb.put("touser", touser);
        }else {
            System.out.println("文字訊息引數不規範,將會發送給所有人!");
            jb.put("touser", "@all");
        }
        if (toparty != null) {
            jb.put("toparty", toparty);
        }
        return jb;
    }

}