JAVA源碼微信公眾號開發 | 第一篇: 前期准備及實現自動回復(附源碼)


JAVA微信公眾號開發 | 第一篇: 前期准備及實現自動回復(附源碼)

本系列文章是記錄自己微信公眾號的開發過程,也希望能為感興趣的其他人提供一些思路和幫助
歡迎轉發,轉發請在文前明顯位置,注明本文地址
項目源碼放到文末,需要自取
最終效果

前言

有一個特別坑的地方,需要提前說一下 個人訂閱號 現在已經沒有接口開發自定義菜單的權限了。

也就是說只能通過微信賬號后台自定義菜單,而不能通過接口開發自定義菜單
但是接口開發和后台自定義兩者互斥

要想接口開發自定義菜單,就必須是認證公眾號,但是

wt fk
雞你太美 誒,,, 雞你太美
但是服務號申請也不難
雖然有這么多限制,我還是想去嘗試一下,
興趣大於一切**

1.申請公眾號

申請服務號 還是比較麻煩的 但是服務號是直接展示在好友消息列表中 而訂閱號是展示在訂閱號消息

2.雲服務器或者其他外網映射工具

我用的是騰訊雲。其他外網映射工具在這里就不說了,搜一下很多

3.接口配置

進入配置頁面:基本配置 > 修改配置

  • URL:中的IP地址,如果是騰訊雲則可以在雲服務器界面找自己的公網IP地址
  • Token :可以自己隨意填,但是要和后面服務器的保持一致

點擊提交>確定
之后微信會自動向你的服務器發送GET請求並驗證你的服務器,因此我們需要完成了對GET請求的處理(后面有代碼講解,先不用點確定)

4.驗證消息的確來自微信服務器

開發者提交信息后,微信服務器將發送GET請求到填寫的服務器地址URL上,GET請求攜帶參數如下表所示:

參數 描述
signature 微信加密簽名,signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數
timestamp 時間戳
nonce 隨機數
echostr 隨機字符串

開發者通過檢驗signature對請求進行校驗(下面有校驗方式)。若確認此次GET請求來自微信服務器,請原樣返回echostr參數內容,則> 接入生效,成為開發者成功,否則接入失敗。
加密/校驗流程如下:
1)將token、timestamp、nonce三個參數進行字典序排序
2)將三個參數字符串拼接成一個字符串進行sha1加密
3)開發者獲得加密后的字符串可與signature對比,標識該請求來源於微信

以上是來源 微信文檔,寫的很清楚了,擼代碼。

/** 
* 處理微信服務器發來的get請求,進行簽名的驗證 
* signature 微信端發來的簽名 * timestamp 微信端發來的時間戳 
* nonce     微信端發來的隨機字符串 
* echostr   微信端發來的驗證字符串 
*/
@GetMapping(value = "wechat")
public String validate(@RequestParam(value = "signature") String signature,        
                            @RequestParam(value = "timestamp") String timestamp,                     
                            @RequestParam(value = "nonce") String nonce,                       
                            @RequestParam(value = "echostr") String echostr) {    
                            
                            return WeChatUtil.checkSignature(signature, timestamp, nonce) ? echostr : null;
                            
}
public static boolean checkSignature(String signature, String timestamp, String nonce) {   
        String[] arr = new String[] { WeChatContant.TOKEN, timestamp, nonce };   
        // 將token、timestamp、nonce三個參數進行字典序排序   
        sort(arr);    
        StringBuilder content = new StringBuilder();   
        for (int i = 0; i < arr.length; i++) {       
            content.append(arr[i]);    
        }    
        MessageDigest md = null;    
        String tmpStr = null;    
        try {        
            md = MessageDigest.getInstance("SHA-1");        
            // 將三個參數字符串拼接成一個字符串進行sha1加密        
            byte[] digest = md.digest(content.toString().getBytes());        
            tmpStr = byteToStr(digest);    
         } catch (NoSuchAlgorithmException e) {       
            e.printStackTrace();    
         }    
        content = null;   
        // 將sha1加密后的字符串可與signature對比,標識該請求來源於微信    
        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
}

String[] arr = new String[] { WeChatContant.TOKEN, timestamp, nonce };
此處的WeChatContant.TOKEN是個常量 public static final String TOKEN = "lhx";
必須和上文基本配置中的 此處隨便寫 保持一致
完成之后 把項目打個JAR包 扔到服務器上面(別忘安裝jdk,安裝方法百度搜一下)
此處用到的工具軟件:**Xshell 6 **和 Xftp 6
工具軟件放到文末,需要自取

<build>    
    <plugins>        
        <plugin>            
            <groupId>org.springframework.boot</groupId>            
            <artifactId>spring-boot-maven-plugin</artifactId>            
            <executions>                
                <execution>                   
                    <configuration>         
                        <!--此處填寫boot啟動類-->               
                        <mainClass>com.lhx.wechat.WechatApplication</mainClass>                                
                    </configuration>                 
                    <goals>                        
                        <goal>repackage</goal>        
                    </goals>      
                </execution>            
            </executions>        
        </plugin>    
    </plugins>
</build>

項目源碼中添加了maven打包插件 可以直接maven clen package -> 可運行的jar包
項目源碼放到文末,需要自取

然后再回到 配置頁面:基本配置 > 修改配置 > 提交 >確定 網頁頂端會顯示提交成功

5.接收普通消息

當普通微信用戶向公眾賬號發消息時,微信服務器將POST消息的XML數據包到開發者填寫的URL上。
請注意:
1、關於重試的消息排重,推薦使用msgid排重。
2、微信服務器在五秒內收不到響應會斷掉連接,並且重新發起請求,總共重試三次。假如服務器無法保證在五秒內處理並回復,可以直接 回復空串,微信服務器不會對此作任何處理,並且不會發起重試。詳情請見“發送消息-被動回復消息”。
3、如果開發者需要對用戶消息在5秒內立即做出回應,即使用“發送消息-被動回復消息”接口向用戶被動回復消息時,可以在公眾平台官網的開發者中心處設置消息加密。開啟加密后,用戶發來的消息和開發者回復的消息都會被加密(但開發者通過客服接口等API調用形式向用戶發送消息,則不受影響)。關於消息加解密的詳細說明,請見“發送消息-被動回復消息加解密說明”。各消息類型的推送XML數據包結構如下:

<xml> 
    <ToUserName><![CDATA[toUser]]></ToUserName>  
    <FromUserName><![CDATA[fromUser]]></FromUserName>  
    <CreateTime>1348831860</CreateTime>  
    <MsgType><![CDATA[text]]></MsgType>  
    <Content><![CDATA[this is a test]]></Content> 
    <MsgId>1234567890123456</MsgId>
</xml>
參數 描述
ToUserName 開發者微信號
FromUserName 發送方帳號(一個OpenID)
CreateTime 消息創建時間 (整型)
MsgType 消息類型,文本為text
Content 文本消息內容
MsgId 消息id,64位整型

文末有源碼

6.回復普通消息

當用戶發送消息給公眾號時(或某些特定的用戶操作引發的事件推送時),會產生一個POST請求,開發者可以在響應包(Get)中返回特> 定XML結構,來對該消息進行響應(現支持回復文本、圖片、圖文、語音、視頻、音樂)。嚴格來說,發送被動響應消息其實並不是一種> 接口,而是對微信服務器發過來消息的一次回復。需要的XML數據包結構如下:

回復文本消息

<xml>  
    <ToUserName><![CDATA[toUser]]></ToUserName>  
    <FromUserName><![CDATA[fromUser]]></FromUserName>  
    <CreateTime>12345678</CreateTime>  
    <MsgType><![CDATA[text]]></MsgType>  
    <Content><![CDATA[你好]]></Content>
</xml>
參數 是否必須 描述
ToUserName 接收方帳號(收到的OpenID)
FromUserName 開發者微信號
CreateTime 消息創建時間 (整型)
MsgType 消息類型,文本為text
Content 回復的消息內容(換行:在content中能夠換行,微信客戶端就支持換行顯示)

文末有源碼

完整代碼

@PostMapping(value = "wechat")
public String textMessge(HttpServletRequest request) {   
    logger.info("wechat");  
    return javaMessageService.textMessage(request);
}
@Service
public class JavaMessageServiceImpl implements JavaMessageService {    
    private static final Logger logger = LoggerFactory.getLogger(JavaMessageServiceImpl.class);    
    @Override    
    public String textMessage(HttpServletRequest request) {        
        logger.info("進來了");      
        // xml格式的消息數據        
        String respXml = null;      
        // 默認返回的文本消息內容       
        String respContent;       
        try {        
            // 調用parseXml方法解析請求消息     
            Map<String,String> requestMap = WeChatUtil.parseXml(request);     
            // 消息類型         
            String msgType = requestMap.get(WeChatContant.MsgType);       
            String mes = null;        

            // 文本消息          
            if (msgType.equals(WeChatContant.REQ_MESSAGE_TYPE_TEXT)) {         
                mes =requestMap.get(WeChatContant.Content);              
                    if(mes != null){                  
                        String content = checkResources(mes);              
                            if(!StringUtils.isBlank(content)) {                   
                            return WeChatUtil.sendTextMsg(requestMap, content);                
                        }           
                     }          
             }           
             // 圖片消息           
             // ......           
             mes = mes == null ? "在嗎" : mes;         
             return WeChatUtil.sendTextMsg(requestMap, mes);   
         
            } catch (DocumentException e) {      
                return null;       
            } catch (Exception e) {         
                e.printStackTrace();   
                return null;   
            }      
            return null;   
            }    
        
            private String checkResources(String message){        
                String returnMessage = null;        
                if("加油".equals(message)){            
                    returnMessage = "你也是";            
                    return returnMessage;        
                }        
                if("我愛你".equals(message)){            
                    returnMessage = "一見面就說愛?";            
                    return returnMessage;        
                }        
                return null;    
            }
        }

測試可以用postman 進行測試

項目源碼和本文用到的所有工具我已經打包好放在了微信公眾號中> "爪哇之父兄弟",
關注后,回復"公眾號源碼",即可獲取
如果你對本文有不對的地方或者遇到難題了 歡迎評論或者掃碼進群 一起討論 免費幫助
如果本文對你有幫助,請小編喝咖啡啊

公眾號 爪哇之父兄弟 微信 支付寶 q群


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM