软件编程
位置:首页>> 软件编程>> java编程>> java版微信公众平台消息接口应用示例

java版微信公众平台消息接口应用示例

作者:wangqianjiao  发布时间:2022-10-04 10:22:58 

标签:java,微信公众平台,消息接口

本文实例讲述了java版微信公众平台消息接口应用方法。分享给大家供大家参考,具体如下:

微信公众平台现在推出自动回复消息接口,但是由于是接口内容用的是PHP语言写的,很多地方操作起来让本人这个对Java比较熟悉的小伙很别扭,所以仿照PHP的接口代码做了一套jsp语言编写的接口。

首先先把整个接口代码贴出来做下比较,然后我们再分析代码:

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为内部类不能使用非final类型的对象
 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");
     }
   }
 }
 //自动回复内容
 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("");
   }
 }
 //微信接口验证
 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;
   }
 }
 //向请求端发送返回数据
 public void print(String content){
   try{
     final_response.getWriter().print(content);
     final_response.getWriter().flush();
     final_response.getWriter().close();
   }catch(Exception e){
   }
 }
 //数组转字符串
 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参数
 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();
%>

首先的从总体看的话,jsp要比PHP繁琐一些,因为很多函数需要自己写,像sha1加密,解析xml字符串等都需要自己找第三方的库。

第一点,我们要获取微信公众平台给jsp发送的post或get参数,正常情况下都是用request.getParameter就可以获取到,但是在写的过程中发现PHP是这样获取


$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

这时通过查询一些资料知道这样获取的是无法通过$_GET或$_POST函数得到的”未识别 MIME 类型的数据“,原始的 POST 数据
(参考:https://www.jb51.net/article/117653.htm)

所以这里使用获取原始数据流的方式来解析post的xml数据


String postStr=null;
try{
 postStr=this.readStreamParameter(final_request.getInputStream());
}catch(Exception e){
 e.printStackTrace();
}


//从输入流读取post参数
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();
}

第二个,是response消息返回给微信平台,我尝试的用最一般的out.print去做,但是发现没反应,观察PHP的代码写法


echo "";
exit;

猜想可能需要有个刷新的操作才能把消息response回去,于是找了下response内的一些函数做出以下尝试


//向请求端发送返回数据
public void print(String content){
   try{
     final_response.getWriter().print(content);
     final_response.getWriter().flush();
     final_response.getWriter().close();
   }catch(Exception e){
   }
}

发现以上做法是可以在微信发送端得到消息的;

第三个,接口描述上说目前只支持80端口的服务端地址,所以我这里的做法是用apache服务器路由到tomcat的jsp上

关于微信公众平台的消息接口的详细介绍,可以参看微信公众平台的官方文档,里面介绍了消息的xml的格式和消息的发送方式等。

希望本文所述对大家java程序设计有所帮助。

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com