首页 > 开发 > Java > 正文

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

2024-07-13 10:09:29
字体:
来源:转载
供稿:网友

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

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

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

PHP:

<?php/** * wechat php test *///define your tokendefine("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();%>

以上就是PHP接口和JSP接口的所有代码,现在我们来对一些需要注意的地方做下分析:

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

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

$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

这时通过查询一些资料知道这样获取的是无法通过$_GET或$_POST函数得到的”未识别 MIME 类型的数据“,原始的 POST 数据
 

所以这里使用获取原始数据流的方式来解析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程序设计有所帮助。


注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表