最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java版微信公眾平臺消息接口應(yīng)用示例

 更新時間:2017年07月03日 10:47:33   作者:wangqianjiao  
這篇文章主要介紹了java版微信公眾平臺消息接口應(yīng)用,結(jié)合實例形式對比分析了PHP與java應(yīng)用微信公眾平臺接口的相關(guān)調(diào)用與操作技巧,需要的朋友可以參考下

本文實例講述了java版微信公眾平臺消息接口應(yīng)用方法。分享給大家供大家參考,具體如下:

微信公眾平臺現(xiàn)在推出自動回復(fù)消息接口,但是由于是接口內(nèi)容用的是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為內(nèi)部類不能使用非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");
      }
    }
  }
  //自動回復(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("");
    }
  }
  //微信接口驗證
  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;
    }
  }
  //向請求端發(fā)送返回數(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)在我們來對一些需要注意的地方做下分析:

首先的從總體看的話,jsp要比PHP繁瑣一些,因為很多函數(shù)需要自己寫,像sha1加密,解析xml字符串等都需要自己找第三方的庫。

第一點,我們要獲取微信公眾平臺給jsp發(fā)送的post或get參數(shù),正常情況下都是用request.getParameter就可以獲取到,但是在寫的過程中發(fā)現(xiàn)PHP是這樣獲取

$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

這時通過查詢一些資料知道這樣獲取的是無法通過$_GET或$_POST函數(shù)得到的”未識別 MIME 類型的數(shù)據(jù)“,原始的 POST 數(shù)據(jù)
(參考:http://www.fzitv.net/article/117653.htm

所以這里使用獲取原始數(shù)據(jù)流的方式來解析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();
}

第二個,是response消息返回給微信平臺,我嘗試的用最一般的out.print去做,但是發(fā)現(xiàn)沒反應(yīng),觀察PHP的代碼寫法

echo "";
exit;

猜想可能需要有個刷新的操作才能把消息response回去,于是找了下response內(nèi)的一些函數(shù)做出以下嘗試

//向請求端發(fā)送返回數(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ā)送端得到消息的;

第三個,接口描述上說目前只支持80端口的服務(wù)端地址,所以我這里的做法是用apache服務(wù)器路由到tomcat的jsp上

關(guān)于微信公眾平臺的消息接口的詳細介紹,可以參看微信公眾平臺的官方文檔,里面介紹了消息的xml的格式和消息的發(fā)送方式等。

更多關(guān)于java算法相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java字符與字符串操作技巧總結(jié)》、《Java數(shù)組操作技巧總結(jié)》、《Java數(shù)學(xué)運算技巧總結(jié)》、《Java編碼操作技巧總結(jié)》和《Java數(shù)據(jù)結(jié)構(gòu)與算法教程

希望本文所述對大家java程序設(shè)計有所幫助。

相關(guān)文章

  • Mybatis-Plus自動填充更新操作相關(guān)字段的實現(xiàn)

    Mybatis-Plus自動填充更新操作相關(guān)字段的實現(xiàn)

    數(shù)據(jù)庫表中應(yīng)該都要有create_time、update_time字段;那么在開發(fā)中,對于這些共有字段的處理應(yīng)該要進行統(tǒng)一,這樣就可以簡化我們的開發(fā)過程。那么本文就對Mybatis-Plus中的字段自動填充進行記錄
    2021-11-11
  • 通過Spring Boot + Mybatis + Redis快速搭建現(xiàn)代化Web項目

    通過Spring Boot + Mybatis + Redis快速搭建現(xiàn)代化Web項目

    本篇文章介紹了如何通過Spring Boot、Mybatis以及Redis快速搭建一個現(xiàn)代化的Web項目,并且同時介紹了如何在Spring Boot下優(yōu)雅地書寫單元測試來保證我們的代碼質(zhì)量。具體內(nèi)容詳情大家通過本文學(xué)習(xí)下吧
    2017-12-12
  • Java實現(xiàn)直接插入排序與折半插入排序的示例詳解

    Java實現(xiàn)直接插入排序與折半插入排序的示例詳解

    這篇文章主要為大家詳細介紹了插入排序中兩個常見的排序:直接插入排序與折半插入排序。本文用Java語言實現(xiàn)了這兩個排序算法,感興趣的可以學(xué)習(xí)一下
    2022-06-06
  • mybatis-generator-gui根據(jù)需求改動示例

    mybatis-generator-gui根據(jù)需求改動示例

    這篇文章主要為大家介紹了mybatis-generator-gui根據(jù)需求改動示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • Spring實戰(zhàn)之協(xié)調(diào)作用域不同步的Bean操作示例

    Spring實戰(zhàn)之協(xié)調(diào)作用域不同步的Bean操作示例

    這篇文章主要介紹了Spring實戰(zhàn)之協(xié)調(diào)作用域不同步的Bean操作,結(jié)合實例形式分析了Spring協(xié)調(diào)作用域不同步的Bean相關(guān)配置及使用技巧,需要的朋友可以參考下
    2019-11-11
  • Spring解析配置類和掃描包路徑的詳細過程

    Spring解析配置類和掃描包路徑的詳細過程

    這篇文章主要介紹了Spring解析配置類和掃描包路徑的詳細過程,文中通過代碼示例講解的非常詳細,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-12-12
  • SpringBoot集成EasyExcel的應(yīng)用場景分析

    SpringBoot集成EasyExcel的應(yīng)用場景分析

    這篇文章主要介紹了SpringBoot集成EasyExcel的應(yīng)用場景,java領(lǐng)域解析、生成excel比較有名的框架有apache poi、jxl等,今天通過實例代碼給大家詳細介紹,需要的朋友可以參考下
    2021-07-07
  • SpringBoot ApplicationListener事件監(jiān)聽接口使用問題探究

    SpringBoot ApplicationListener事件監(jiān)聽接口使用問題探究

    這篇文章主要介紹了SpringBoot ApplicationListener事件監(jiān)聽接口使用問題,自定義監(jiān)聽器需要實現(xiàn)ApplicationListener接口,實現(xiàn)對應(yīng)的方法來完成自己的業(yè)務(wù)邏輯。SpringBoot Application共支持6種事件監(jiān)聽
    2023-04-04
  • 教你如何測試Spring Data JPA的Repository

    教你如何測試Spring Data JPA的Repository

    Spring Data JPA 提供了一些便捷的方式來測試這種持久層的代碼,常見的兩種測試類型是集成測試和單元測試,本文通過示例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • java高級用法之綁定CPU的線程Thread?Affinity簡介

    java高級用法之綁定CPU的線程Thread?Affinity簡介

    java線程thread affinity是用來將java代碼中的線程綁定到CPU特定的核上,用來提升程序運行的性能,這篇文章主要介紹了java高級用法之綁定CPU的線程thread affinity的相關(guān)知識,需要的朋友可以參考下
    2022-05-05

最新評論

巩留县| 家居| 霞浦县| 甘谷县| 盐城市| 珲春市| 昌平区| 成安县| 荆州市| 潞城市| 潞城市| 许昌市| 三穗县| 迁西县| 沛县| 炎陵县| 芦山县| 太原市| 奉贤区| 万安县| 仙桃市| 鹤岗市| 汽车| 西贡区| 景宁| 孟连| 醴陵市| 蕉岭县| 巴林右旗| 望谟县| 阳信县| 芦溪县| 洪洞县| 大埔县| 东乌| 大新县| 平阳县| 巩留县| 荥阳市| 云阳县| 额敏县|