java版微信公眾平臺(tái)消息接口應(yīng)用示例
本文實(shí)例講述了java版微信公眾平臺(tái)消息接口應(yīng)用方法。分享給大家供大家參考,具體如下:
微信公眾平臺(tái)現(xiàn)在推出自動(dòng)回復(fù)消息接口,但是由于是接口內(nèi)容用的是PHP語(yǔ)言寫的,很多地方操作起來(lái)讓本人這個(gè)對(duì)Java比較熟悉的小伙很別扭,所以仿照PHP的接口代碼做了一套jsp語(yǔ)言編寫的接口。
首先先把整個(gè)接口代碼貼出來(lái)做下比較,然后我們?cè)俜治龃a:
PHP:
<?php /** * wechat php test */ //define your token define("TOKEN", "weixin"); $wechatObj = new wechatCallbackapiTest(); $wechatObj->valid(); class wechatCallbackapiTest { public function valid() { $echoStr = $_GET["echostr"]; //valid signature , option if($this->checkSignature()){ echo $echoStr; exit; } } public function responseMsg() { //get post data, May be due to the different environments $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //extract post data if (!empty($postStr)){ $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $keyword = trim($postObj->Content); $time = time(); $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> <FuncFlag>0</FuncFlag> </xml>"; if(!empty( $keyword )) { $msgType = "text"; $contentStr = "Welcome to wechat world!"; $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); echo $resultStr; }else{ echo "Input something..."; } }else { echo ""; exit; } } private function checkSignature() { $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr); $tmpStr = implode( $tmpArr ); $tmpStr = sha1( $tmpStr ); if( $tmpStr == $signature ){ return true; }else{ return false; } } } ?>
JAVA:
<%@page import="java.util.Date"%> <%@page import="org.dom4j.Element"%> <%@page import="org.dom4j.DocumentHelper"%> <%@page import="org.dom4j.Document"%> <%@page import="java.io.IOException"%> <%@page import="java.io.InputStreamReader"%> <%@page import="java.io.BufferedReader"%> <%@page import="java.io.Reader"%> <%@page import="java.security.MessageDigest"%> <%@page import="java.util.Arrays"%> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <% //WeiXinHandler為內(nèi)部類不能使用非final類型的對(duì)象 final String TOKEN="weixin"; final HttpServletRequest final_request=request; final HttpServletResponse final_response=response; %> <% class WeiXinHandler{ public void valid(){ String echostr=final_request.getParameter("echostr"); if(null==echostr||echostr.isEmpty()){ responseMsg(); }else{ if(this.checkSignature()){ this.print(echostr); }else{ this.print("error"); } } } //自動(dòng)回復(fù)內(nèi)容 public void responseMsg(){ String postStr=null; try{ postStr=this.readStreamParameter(final_request.getInputStream()); }catch(Exception e){ e.printStackTrace(); } //System.out.println(postStr); if (null!=postStr&&!postStr.isEmpty()){ Document document=null; try{ document = DocumentHelper.parseText(postStr); }catch(Exception e){ e.printStackTrace(); } if(null==document){ this.print(""); return; } Element root=document.getRootElement(); String fromUsername = root.elementText("FromUserName"); String toUsername = root.elementText("ToUserName"); String keyword = root.elementTextTrim("Content"); String time = new Date().getTime()+""; String textTpl = "<xml>"+ "<ToUserName><![CDATA[%1$s]]></ToUserName>"+ "<FromUserName><![CDATA[%2$s]]></FromUserName>"+ "<CreateTime>%3$s</CreateTime>"+ "<MsgType><![CDATA[%4$s]]></MsgType>"+ "<Content><![CDATA[%5$s]]></Content>"+ "<FuncFlag>0</FuncFlag>"+ "</xml>"; if(null!=keyword&&!keyword.equals("")) { String msgType = "text"; String contentStr = "Welcome to wechat world!"; String resultStr = textTpl.format(textTpl, fromUsername, toUsername, time, msgType, contentStr); this.print(resultStr); }else{ this.print("Input something..."); } }else { this.print(""); } } //微信接口驗(yàn)證 public boolean checkSignature(){ String signature = final_request.getParameter("signature"); String timestamp = final_request.getParameter("timestamp"); String nonce = final_request.getParameter("nonce"); String token=TOKEN; String[] tmpArr={token,timestamp,nonce}; Arrays.sort(tmpArr); String tmpStr=this.ArrayToString(tmpArr); tmpStr=this.SHA1Encode(tmpStr); if(tmpStr.equalsIgnoreCase(signature)){ return true; }else{ return false; } } //向請(qǐng)求端發(fā)送返回?cái)?shù)據(jù) public void print(String content){ try{ final_response.getWriter().print(content); final_response.getWriter().flush(); final_response.getWriter().close(); }catch(Exception e){ } } //數(shù)組轉(zhuǎn)字符串 public String ArrayToString(String [] arr){ StringBuffer bf = new StringBuffer(); for(int i = 0; i < arr.length; i++){ bf.append(arr[i]); } return bf.toString(); } //sha1加密 public String SHA1Encode(String sourceString) { String resultString = null; try { resultString = new String(sourceString); MessageDigest md = MessageDigest.getInstance("SHA-1"); resultString = byte2hexString(md.digest(resultString.getBytes())); } catch (Exception ex) { } return resultString; } public final String byte2hexString(byte[] bytes) { StringBuffer buf = new StringBuffer(bytes.length * 2); for (int i = 0; i < bytes.length; i++) { if (((int) bytes[i] & 0xff) < 0x10) { buf.append("0"); } buf.append(Long.toString((int) bytes[i] & 0xff, 16)); } return buf.toString().toUpperCase(); } //從輸入流讀取post參數(shù) public String readStreamParameter(ServletInputStream in){ StringBuilder buffer = new StringBuilder(); BufferedReader reader=null; try{ reader = new BufferedReader(new InputStreamReader(in)); String line=null; while((line = reader.readLine())!=null){ buffer.append(line); } }catch(Exception e){ e.printStackTrace(); }finally{ if(null!=reader){ try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return buffer.toString(); } } %> <% WeiXinHandler handler=new WeiXinHandler(); handler.valid(); %>
以上就是PHP接口和JSP接口的所有代碼,現(xiàn)在我們來(lái)對(duì)一些需要注意的地方做下分析:
首先的從總體看的話,jsp要比PHP繁瑣一些,因?yàn)楹芏嗪瘮?shù)需要自己寫,像sha1加密,解析xml字符串等都需要自己找第三方的庫(kù)。
第一點(diǎn),我們要獲取微信公眾平臺(tái)給jsp發(fā)送的post或get參數(shù),正常情況下都是用request.getParameter就可以獲取到,但是在寫的過(guò)程中發(fā)現(xiàn)PHP是這樣獲取
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
這時(shí)通過(guò)查詢一些資料知道這樣獲取的是無(wú)法通過(guò)$_GET或$_POST函數(shù)得到的”未識(shí)別 MIME 類型的數(shù)據(jù)“,原始的 POST 數(shù)據(jù)
(參考:http://chabaoo.cn/article/117653.htm)
所以這里使用獲取原始數(shù)據(jù)流的方式來(lái)解析post的xml數(shù)據(jù)
String postStr=null; try{ postStr=this.readStreamParameter(final_request.getInputStream()); }catch(Exception e){ e.printStackTrace(); }
//從輸入流讀取post參數(shù) public String readStreamParameter(ServletInputStream in){ StringBuilder buffer = new StringBuilder(); BufferedReader reader=null; try{ reader = new BufferedReader(new InputStreamReader(in)); String line=null; while((line = reader.readLine())!=null){ buffer.append(line); } }catch(Exception e){ e.printStackTrace(); }finally{ if(null!=reader){ try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return buffer.toString(); }
第二個(gè),是response消息返回給微信平臺(tái),我嘗試的用最一般的out.print去做,但是發(fā)現(xiàn)沒(méi)反應(yīng),觀察PHP的代碼寫法
echo ""; exit;
猜想可能需要有個(gè)刷新的操作才能把消息response回去,于是找了下response內(nèi)的一些函數(shù)做出以下嘗試
//向請(qǐng)求端發(fā)送返回?cái)?shù)據(jù) public void print(String content){ try{ final_response.getWriter().print(content); final_response.getWriter().flush(); final_response.getWriter().close(); }catch(Exception e){ } }
發(fā)現(xiàn)以上做法是可以在微信發(fā)送端得到消息的;
第三個(gè),接口描述上說(shuō)目前只支持80端口的服務(wù)端地址,所以我這里的做法是用apache服務(wù)器路由到tomcat的jsp上
關(guān)于微信公眾平臺(tái)的消息接口的詳細(xì)介紹,可以參看微信公眾平臺(tái)的官方文檔,里面介紹了消息的xml的格式和消息的發(fā)送方式等。
更多關(guān)于java算法相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java字符與字符串操作技巧總結(jié)》、《Java數(shù)組操作技巧總結(jié)》、《Java數(shù)學(xué)運(yùn)算技巧總結(jié)》、《Java編碼操作技巧總結(jié)》和《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
springboot項(xiàng)目啟動(dòng)慢的問(wèn)題排查方式
這篇文章主要介紹了springboot項(xiàng)目啟動(dòng)慢的問(wèn)題排查方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09Java基礎(chǔ)之Comparable與Comparator概述
這篇文章主要介紹了Java基礎(chǔ)之Comparable與Comparator詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04idea2019版Plugins中搜索不到任何插件的問(wèn)題解決
本文主要介紹了idea2019版Plugins中搜索不到任何插件的問(wèn)題解決,插件搜不出來(lái)的主要原因是plugins.jetbrains.com ping不通,下面就來(lái)介紹一下解決方法,感興趣的可以了解一下2023-09-09Spring mvc是如何實(shí)現(xiàn)與數(shù)據(jù)庫(kù)的前后端的連接操作的?
今天給大家?guī)?lái)的是關(guān)于Spring mvc的相關(guān)知識(shí),文章圍繞著Spring mvc是如何實(shí)現(xiàn)與數(shù)據(jù)庫(kù)的前后端的連接操作的展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06