ホームページ WeChat アプレット WeChatの開発 Java WeChat 開発 API の 2 番目のステップを分析して、メッセージを取得して返信する

Java WeChat 開発 API の 2 番目のステップを分析して、メッセージを取得して返信する

Mar 13, 2017 pm 01:06 PM

この記事では、主に Java WeChat 開発の第 2 ステップ API を分析して、メッセージを取得して返信する方法を説明します。

1. 説明

* この例は、WeChat 開発ドキュメントに基づいています:

http://mp.weixin.qq.com/wiki/home/index.html最新バージョン (2016 年 4 月 3 日 5:34:午後 36 時) 開発デモを実施します。 * 編集プラットフォーム: myeclipse10.7+win32+jdk1.7+tomcat7.0
* サーバー: Alibaba Cloud Windows Server 2008 64 ビット* プラットフォーム要件: サーブレット
アノテーション メソッドを使用、プラットフォーム要件: j2ee6.0+、jdk6。 0+、tomcat7.0+
* このデモでは、API 分析に重点を置いています。
* テストの説明を容易にするために、各テスト ケースは独立しており、他のメソッドに依存しません。梱包についてはあまり考えないでください。 * デモは、可能な限り API 要件に従って実行する必要があります。その目的は、ドキュメントの使用方法を理解し、1 つの例から推測する効果を達成することです。 * 知識要件: しっかりした Java の基礎、http ネットワーク通信の知識、javaweb の十分な理解、
json
解析
* 各記事の最後に、この部分のデモ ソース コードが示されます。 API を分析した後、すべてのデモ ソース コードはソース コード パッケージの形式で提供されます。
* 現在時刻: 2016 年 4 月 3 日 5:32:57 PM、今回の対象となります。
2. 元のドキュメント - メッセージ管理 (
要約

)

•ドキュメントのアドレス: http://mp.weixin.qq.com/wiki/17/f298879f8fb29ab98b2f2971d42552fd.html
•メッセージ管理

◦ メッセージの受信 - 通常のメッセージの受信

◦ メッセージの受信 - イベントプッシュの受信 ◦ メッセージの送信 - パッシブ応答メッセージ ◦ メッセージの送信 - パッシブ応答中の暗号化と復号化
◦ メッセージの送信 - カスタマーサービスメッセージ
◦ メッセージの送信 - グループ送信インターフェース
◦ メッセージ送信 - テンプレートメッセージインターフェース
◦ メッセージ送信 - テンプレートメッセージ動作仕様
◦ 公開アカウントの自動返信設定の取得


3. 文書理解

• メッセージ受信
◦ 文書通常の WeChat ユーザーが公開アカウントにメッセージを送信すると、WeChat サーバーは POST メッセージの XML
データを開発者が入力した URL にパッケージ化します。
理解: WeChat サーバーは、ユーザーが req に送信したメッセージをポスト ストリームの形式で返します。ユーザーが送信したメッセージを取得したい場合は、req.getInputStream() を通じて取得できます。もちろん、ドキュメントで返されたメッセージの XML 形式に基づいて必要な解析を実行できます。
実装:

/*
 * 该部分我们获取用户发送的信息,并且解析成<K,V>的形式进行显示
 */
// 解析用户发送过来的信息
InputStream is = req.getInputStream();// 拿取请求流
// 将解析结果存储在HashMap中
Map<String, String> map = new HashMap<String, String>();
// 解析xml,将获取到的返回结果xml进行解析成我们习惯的文字信息
SAXReader reader = new SAXReader();// 第三方jar:dom4j【百度:saxreader解析xml】
Document document = null;
try {
 document = reader.read(is);
} catch (DocumentException e1) {
 // TODO Auto-generated catch block
 e1.printStackTrace();
}
// 得到xml根元素
Element root = document.getRootElement();
// 得到根元素的所有子节点
List<Element> elementList = root.elements();

// 遍历所有子节点
for (Element e : elementList)
 map.put(e.getName(), e.getText());

// 测试输出
Set<String> keySet = map.keySet();
// 测试输出解析后用户发过来的信息
System.out.println(TAG + ":解析用户发送过来的信息开始");
for (String key : keySet) {
 System.out.println(key + ":" + map.get(key));
}
System.out.println(TAG + ":解析用户发送过来的信息结束");
ログイン後にコピー



•メッセージを送信する

◦ドキュメントでは次のように説明されています: ユーザーが公式アカウントにメッセージを送信するとき (または特定のユーザー操作によりイベントがプッシュされるとき)、POSTリクエストが生成されると、開発者は応答パッケージ (Get) で特定の XML 構造を返すことでメッセージに応答できます (応答テキスト、
写真
、グラフィックス、テキスト、音声、
ビデオ、音楽をサポートするようになりました)。厳密に言えば、受動的応答メッセージの送信は実際にはインターフェイスではなく、WeChat サーバーによって送信されたメッセージに対する応答です。 理解: ユーザーがリクエストを送信すると、POST リクエストが生成され、Respone を通じてメッセージに返信できます。ただし、返信コンテンツには厳密な形式要件があり、形式要件が満たされている場合にのみ、WeChat サーバーはそれを処理してユーザーに返します。ドキュメントの「メッセージ管理」モジュールを見ると、WeChat にはさまざまなメッセージがあることがわかります。メッセージの種類ごとに、特定の情報をユーザーに正常に返すための要件に従う必要があります。ユーザーのテキスト メッセージとグラフィック メッセージには、ドキュメントで必要な形式で返信するよう努めます。キーポイント: ドキュメントの要件に従って必要なパラメータを構築します。特記事項: パラメータでは大文字と小文字が区別されます。 ◦ 実装 1-通常のテキストメッセージへの返信:

//实例1:发送普通文本消息,请查看文档关于“回复文本消息”的xml格式

// 第一步:按照回复文本信息构造需要的参数
TextMsg textMsg = new TextMsg();
textMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反
textMsg.setFromUserName(map.get("ToUserName"));
textMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型)
textMsg.setMsgType("text");// 文本类型消息
textMsg.setContent("我是服务器回复给用户的信息");

// // 第二步,将构造的信息转化为微信识别的xml格式【百度:xstream bean转xml】
XStream xStream = new XStream();
xStream.alias("xml", textMsg.getClass());
String textMsg2Xml = xStream.toXML(textMsg);
System.out.println(textMsg2Xml);

// // 第三步,发送xml的格式信息给微信服务器,服务器转发给用户
PrintWriter printWriter = resp.getWriter();
printWriter.print(textMsg2Xml);
ログイン後にコピー
◦ 実装 2-グラフィックメッセージへの返信:
//实例2,发送图文消息。请查看文档关于“回复图文消息”的xml格式

// 第一步:按照回复图文信息构造需要的参数
List<Article> articles = new ArrayList<Article>();
Article a = new Article();
a.setTitle("我是图片标题");
a.setUrl("www.baidu.com");// 该地址是点击图片跳转后
a.setPicUrl("http://b.hiphotos.baidu.com/image/pic/item/08f790529822720ea5d058ba7ccb0a46f21fab50.jpg");// 该地址是一个有效的图片地址
a.setDescription("我是图片的描述");
articles.add(a);
PicAndTextMsg picAndTextMsg = new PicAndTextMsg();
picAndTextMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反
picAndTextMsg.setFromUserName(map.get("ToUserName"));
picAndTextMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型)
picAndTextMsg.setMsgType("news");// 图文类型消息
picAndTextMsg.setArticleCount(1);
picAndTextMsg.setArticles(articles);
// 第二步,将构造的信息转化为微信识别的xml格式【百度:xstream bean转xml】
XStream xStream = new XStream();
xStream.alias("xml", picAndTextMsg.getClass());
xStream.alias("item", a.getClass());
String picAndTextMsg2Xml = xStream.toXML(picAndTextMsg);
System.out.println(picAndTextMsg2Xml);
// 第三步,发送xml的格式信息给微信服务器,服务器转发给用户
PrintWriter printWriter = resp.getWriter();
printWriter.print(picAndTextMsg2Xml);
ログイン後にコピー


この部分のすべての操作ソースコードは直接使用できます

•CoreServlet.java (サーバーアクセス、受信を含む)ユーザーメッセージ メッセージ、通常のテキストメッセージへの返信、グラフィックメッセージへの返信 サードパーティの jar が必要: dom4j、xstream)

package com.gist.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.gist.bean.Article;
import com.gist.bean.PicAndTextMsg;
import com.thoughtworks.xstream.XStream;

/**
 * @author 高远</n> 邮箱:wgyscsf@163.com</n> 博客 http://www.php.cn/;/n>
 *  编写时期 2016-4-3 下午4:34:05
 */
@WebServlet("/CoreServlet")
public class CoreServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;
 String TAG = "CoreServlet";

 /*
 * 第二步:验证服务器地址的有效性 开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,
 * GET请求携带四个参数:signature、timestamp、nonce、echostr
 * 开发者通过检验signature对请求进行校验(下面有校验方式)。 若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,
 * 则接入生效, 成为开发者成功,否则接入失败。
 * 
 * 加密/校验流程如下: 1. 将token、timestamp、nonce三个参数进行字典序排序 2.
 * 将三个参数字符串拼接成一个字符串进行sha1加密 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
 */
 /*
 * 字典排序(lexicographical
 * order)是一种对于随机变量形成序列的排序方法。其方法是,按照字母顺序,或者数字小大顺序,由小到大的形成序列。
 */
 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  throws ServletException, IOException {

 // 设置编码
 req.setCharacterEncoding("utf-8");
 resp.setContentType("html/text;charset=utf-8");
 resp.setCharacterEncoding("utf-8");
 // 获取输出流
 PrintWriter printWriter = resp.getWriter();

 // 设置一个全局的token,开发者自己设置。api这样解释:Token可由开发者可以任意填写,
 // 用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)
 String token = "wgyscsf";
 // 根据api说明,获取上述四个参数
 String signature = req.getParameter("signature");
 String timestamp = req.getParameter("timestamp");
 String nonce = req.getParameter("nonce");
 String echostr = req.getParameter("echostr");
 // // temp:临时打印,观看返回参数情况
 // System.out.println(TAG + ":signature:" + signature + ",timestamp:"
 // + timestamp + ",nonce:" + nonce + ",echostr:" + echostr);
 // 根据api所说的“加密/校验流程”进行接入。共计三步

 // 第一步:将token、timestamp、nonce三个参数进行字典序排序
 String[] parms = new String[] { token, timestamp, nonce };// 将需要字典序排列的字符串放到数组中
 Arrays.sort(parms);// 按照api要求进行字典序排序
 // 第二步:将三个参数字符串拼接成一个字符串进行sha1加密
 // 拼接字符串
 String parmsString = "";// 注意,此处不能=null。
 for (int i = 0; i < parms.length; i++) {
  parmsString += parms[i];
 }
 // sha1加密
 String mParms = null;// 加密后的结果
 MessageDigest digest = null;
 try {
  digest = java.security.MessageDigest.getInstance("SHA");
 } catch (NoSuchAlgorithmException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 digest.update(parmsString.getBytes());
 byte messageDigest[] = digest.digest();
 // Create Hex String
 StringBuffer hexString = new StringBuffer();
 // 字节数组转换为 十六进制 数
 for (int i = 0; i < messageDigest.length; i++) {
  String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
  if (shaHex.length() < 2) {
  hexString.append(0);
  }
  hexString.append(shaHex);
 }
 mParms = hexString.toString();// 加密结果

 /*
  * api要求: 若确认此次GET请求来自微信服务器,请原样返回echostr参数内容, 则接入生效, 成为开发者成功,否则接入失败。
  */
 // 第三步: 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信接入成功。
 // System.out.println(TAG + ":" + mParms + "---->" + signature);
 if (mParms.equals(signature)) {
  // System.out.println(TAG + ":" + mParms + "---->" + signature);
  printWriter.write(echostr);
 } else {
  // 接入失败,不用回写
  // System.out.println(TAG + "接入失败");
 }
 }

 /*
 * 查看api文档关于收发消息推送的消息格式基本一致。 如以下格式: <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> 那么,我们就可以进行统一处理。
 */
 /*
 * 我们先获取输入流,看输入流里面的信息。通过测试打印输出流,我们可以看到每次用户请求,都会收到req请求,请求格式是xml格式,该信息在文档中有说明。
 */
 /*
 * 特别注意,req.getInputStream()只能获取一次,并且只能读取一次。如果想要多次读取,需要另外想办法。为了简单起见,
 * 我们只获取一次req.getInputStream(),不再打印输出流信息。直接打印解析后的信息。
 */
 @Override
 protected void doPost(HttpServletRequest req, HttpServletResponse resp)
  throws ServletException, IOException {
 // 设置编码
 req.setCharacterEncoding("utf-8");
 resp.setContentType("html/text;charset=utf-8");
 resp.setCharacterEncoding("utf-8");

 /*
  * 该部分我们获取用户发送的信息,并且解析成<K,V>的形式进行显示
  */
 // 解析用户发送过来的信息
 InputStream is = req.getInputStream();// 拿取请求流
 // 将解析结果存储在HashMap中
 Map<String, String> map = new HashMap<String, String>();
 // 解析xml,将获取到的返回结果xml进行解析成我们习惯的文字信息
 SAXReader reader = new SAXReader();// 第三方jar:dom4j【百度:saxreader解析xml】
 Document document = null;
 try {
  document = reader.read(is);
 } catch (DocumentException e1) {
  // TODO Auto-generated catch block
  e1.printStackTrace();
 }
 // 得到xml根元素
 Element root = document.getRootElement();
 // 得到根元素的所有子节点
 List<Element> elementList = root.elements();

 // 遍历所有子节点
 for (Element e : elementList)
  map.put(e.getName(), e.getText());

 // 测试输出
 Set<String> keySet = map.keySet();
 // 测试输出解析后用户发过来的信息
 System.out.println(TAG + ":解析用户发送过来的信息开始");
 for (String key : keySet) {
  System.out.println(key + ":" + map.get(key));
 }
 System.out.println(TAG + ":解析用户发送过来的信息结束");

 /*
  * 该部分我们尝试按照文档的要求格式给用户回复文本信息、图文消息。重点:按照文档要求构造需要的参数。特别注意:参数区分大小写。
  */

 // //实例1:发送普通文本消息,请查看文档关于“回复文本消息”的xml格式
 //
 // // 第一步:按照回复文本信息构造需要的参数
 // TextMsg textMsg = new TextMsg();
 // textMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反
 // textMsg.setFromUserName(map.get("ToUserName"));
 // textMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型)
 // textMsg.setMsgType("text");// 文本类型消息
 // textMsg.setContent("我是服务器回复给用户的信息");
 //
 // // // 第二步,将构造的信息转化为微信识别的xml格式【百度:xstream bean转xml】
 // XStream xStream = new XStream();
 // xStream.alias("xml", textMsg.getClass());
 // String textMsg2Xml = xStream.toXML(textMsg);
 // System.out.println(textMsg2Xml);
 //
 // // // 第三步,发送xml的格式信息给微信服务器,服务器转发给用户
 // PrintWriter printWriter = resp.getWriter();
 // printWriter.print(textMsg2Xml);

 // //实例2,发送图文消息。请查看文档关于“回复图文消息”的xml格式

 // 第一步:按照回复图文信息构造需要的参数
 List<Article> articles = new ArrayList<Article>();
 Article a = new Article();
 a.setTitle("我是图片标题");
 a.setUrl("www.baidu.com");// 该地址是点击图片跳转后
 a.setPicUrl("http://b.hiphotos.baidu.com/image/pic/item/08f790529822720ea5d058ba7ccb0a46f21fab50.jpg");// 该地址是一个有效的图片地址
 a.setDescription("我是图片的描述");
 articles.add(a);
 PicAndTextMsg picAndTextMsg = new PicAndTextMsg();
 picAndTextMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反
 picAndTextMsg.setFromUserName(map.get("ToUserName"));
 picAndTextMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型)
 picAndTextMsg.setMsgType("news");// 图文类型消息
 picAndTextMsg.setArticleCount(1);
 picAndTextMsg.setArticles(articles);
 // 第二步,将构造的信息转化为微信识别的xml格式【百度:xstream bean转xml】
 XStream xStream = new XStream();
 xStream.alias("xml", picAndTextMsg.getClass());
 xStream.alias("item", a.getClass());
 String picAndTextMsg2Xml = xStream.toXML(picAndTextMsg);
 System.out.println(picAndTextMsg2Xml);
 // 第三步,发送xml的格式信息给微信服务器,服务器转发给用户
 PrintWriter printWriter = resp.getWriter();
 printWriter.print(picAndTextMsg2Xml);
 }
}
ログイン後にコピー

•TestMsg.java (通常のテキストメッセージ Bean)

package com.gist.bean;

/**
 * @author 高远</n> 邮箱:wgyscsf@163.com</n> 博客 http://www.php.cn/;/n>
 *  编写时期 2016-4-4 下午2:09:27
 */
public class TextMsg {
 private String ToUserName;
 private String FromUserName;
 private long CreateTime;
 private String MsgType;

 @Override
 public String toString() {
 return "TextMsg [ToUserName=" + ToUserName + ", FromUserName="
  + FromUserName + ", CreateTime=" + CreateTime + ", MsgType="
  + MsgType + ", Content=" + Content + "]";
 }

 private String Content;

 public TextMsg(String toUserName, String fromUserName, long createTime,
  String msgType, String content) {
 super();
 ToUserName = toUserName;
 FromUserName = fromUserName;
 CreateTime = createTime;
 MsgType = msgType;
 Content = content;
 }

 public TextMsg() {
 super();
 }

 public String getToUserName() {
 return ToUserName;
 }

 public void setToUserName(String toUserName) {
 ToUserName = toUserName;
 }

 public String getFromUserName() {
 return FromUserName;
 }

 public void setFromUserName(String fromUserName) {
 FromUserName = fromUserName;
 }

 public long getCreateTime() {
 return CreateTime;
 }

 public void setCreateTime(long createTime) {
 CreateTime = createTime;
 }

 public String getMsgType() {
 return MsgType;
 }

 public void setMsgType(String msgType) {
 MsgType = msgType;
 }

 public String getContent() {
 return Content;
 }

 public void setContent(String content) {
 Content = content;
 }
}
ログイン後にコピー

•Article.java (グラフィック内のアーティクル Bean)メッセージ)

package com.gist.bean;

/**
 * @author 高远</n> 邮箱:wgyscsf@163.com</n> 博客 http://www.php.cn/;/n>
 *  编写时期 2016-4-4 下午2:47:08
 */
public class Article {
 private String Title;

 @Override
 public String toString() {
 return "item [Title=" + Title + ", Description=" + Description
  + ", PicUrl=" + PicUrl + ", Url=" + Url + "]";
 }

 public String getTitle() {
 return Title;
 }

 public void setTitle(String title) {
 Title = title;
 }

 public String getDescription() {
 return Description;
 }

 public void setDescription(String description) {
 Description = description;
 }

 public String getPicUrl() {
 return PicUrl;
 }

 public void setPicUrl(String picUrl) {
 PicUrl = picUrl;
 }

 public String getUrl() {
 return Url;
 }

 public void setUrl(String url) {
 Url = url;
 }

 private String Description;
 private String PicUrl;
 private String Url;

}
ログイン後にコピー

•PicAndTextMsg.java (画像およびテキストメッセージ Bean)


package com.gist.bean;

import java.util.List;

/**
 * @author 高远</n> 邮箱:wgyscsf@163.com</n> 博客 http://www.php.cn/;/n>
 *  编写时期 2016-4-4 下午2:47:08
 */
public class PicAndTextMsg {
 private String ToUserName;
 private String FromUserName;
 private long CreateTime;
 private String MsgType;
 private int ArticleCount;
 private List<Article> Articles;

 @Override
 public String toString() {
 return "PicAndTextMsg [ToUserName=" + ToUserName + ", FromUserName="
  + FromUserName + ", CreateTime=" + CreateTime + ", MsgType="
  + MsgType + ", ArticleCount=" + ArticleCount + ", Articles="
  + Articles + "]";
 }

 public String getToUserName() {
 return ToUserName;
 }

 public void setToUserName(String toUserName) {
 ToUserName = toUserName;
 }

 public String getFromUserName() {
 return FromUserName;
 }

 public void setFromUserName(String fromUserName) {
 FromUserName = fromUserName;
 }

 public long getCreateTime() {
 return CreateTime;
 }

 public void setCreateTime(long createTime) {
 CreateTime = createTime;
 }

 public String getMsgType() {
 return MsgType;
 }

 public void setMsgType(String msgType) {
 MsgType = msgType;
 }

 public int getArticleCount() {
 return ArticleCount;
 }

 public void setArticleCount(int articleCount) {
 ArticleCount = articleCount;
 }

 public List<Article> getArticles() {
 return Articles;
 }

 public void setArticles(List<Article> articles) {
 Articles = articles;
 }

}
ログイン後にコピー

以上がJava WeChat 開発 API の 2 番目のステップを分析して、メッセージを取得して返信するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)