下面是“Java版微信公众平台后台接入”的完整攻略。
什么是微信公众平台后台接入
微信公众平台后台接入,又称为微信公众号开发,指的是将自己的服务与微信公众平台对接,实现在微信公众号中提供各种服务的开发行为。接入微信公众平台后,就能够使用微信公众平台提供的各种能力,比如自定义菜单、消息推送、客服消息、素材管理等。
步骤
1. 注册成为微信公众号开发者
首先需要在微信公众平台注册成为开发者,然后进入开发者中心获取开发者ID和开发者密钥。注册地址:https://mp.weixin.qq.com/
2. 构建本地开发环境
需要安装Java开发环境(JDK)、Maven(项目管理工具)和一个Java Web框架,比如Spring MVC。
3. 接入微信公众平台
3.1 配置服务器URL和token
在微信公众平台开发者中心,设置服务器URL和token,使得微信公众平台能够向开发者服务器发送请求。将token和微信服务器传送过来的参数进行比较从而验证微信服务器的身份信息。
示例:
服务器URL:http://example.com/weixin
token:MyToken
3.2 验证开发者服务器与微信服务器通信
-
在公众平台开发者中心,可以设置接口配置信息,输入服务器配置URL和Token,微信服务器会向开发者服务器验证身份。首先进入“开发者中心”,然后进入“基本配置”,将服务器“URL”和“Token”填入,保存即可完成服务器配置。
-
验证token接口。微信服务器在配置服务器后会首先尝试访问token接口,比较token的值是否和设置的值相同,从而确认身份信息。验证方法需要在开发者服务器上编写一个Controller,代码如下:
public class TokenController {
// 与开发者中心的Token一致
public static final String TOKEN = "MyToken";
// 处理微信服务器发来的GET请求,进行身份验证
@RequestMapping(value = "/", method = RequestMethod.GET)
@ResponseBody
public String validate(@RequestParam(value = "signature") String signature,
@RequestParam(value = "timestamp") String timestamp,
@RequestParam(value = "nonce") String nonce,
@RequestParam(value = "echostr") String echostr) {
String[] arr = {TOKEN, timestamp, nonce};
// 将Token、timestamp、nonce三个参数进行字典序排序
Arrays.sort(arr);
StringBuilder sb = new StringBuilder();
for (String s : arr) {
sb.append(s);
}
// 对三个参数字符串拼接成一个字符串进行SHA1加密
String result = DigestUtils.sha1Hex(sb.toString());
// 将加密后的字符串与signature进行比较
if (result.equals(signature)) {
// 验证成功后返回echostr,表示验证成功
return echostr;
} else {
// 验证失败返回空
return "";
}
}
}
- 以SpringMVC为例,将该Controller配置到web.xml文件中。
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/weixin</url-pattern>
</servlet-mapping>
4. 接收和回复消息
当用户向公众号发送消息时,微信服务器把消息传递到开发者服务器,开发者服务器接收消息后进行处理并返回响应给微信服务器,微信服务器再把响应返回给用户。
4.1 配置消息接收URL
和配置服务器URL和token一样,在微信公众平台开发者中心设置接收消息的URL。
URL:http://example.com/weixin/message
4.2 接收消息
将微信服务器发来的XML数据进行解析,将消息内容封装成Msg对象。根据不同类型的消息进行处理,比如回复文本消息、回复图片消息等。
示例:
public class MessageController {
@RequestMapping(value = "/message", method = RequestMethod.POST)
@ResponseBody
public String receive(HttpServletRequest request) {
Msg msg = parseRequestMessage(request);
String respXml = "";
switch (msg.getMsgType()) {
case "text":
respXml = buildTextResponseXml(msg, "你好,我是机器人!");
break;
case "image":
respXml = buildImageResponseXml(msg, "media_id");
break;
default:
break;
}
return respXml;
}
private Msg parseRequestMessage(HttpServletRequest request) {
// 解析XML数据
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(request.getInputStream());
Element root = doc.getDocumentElement();
String toUserName = root.getElementsByTagName("ToUserName").item(0).getTextContent();
String fromUserName = root.getElementsByTagName("FromUserName").item(0).getTextContent();
String createTime = root.getElementsByTagName("CreateTime").item(0).getTextContent();
String msgType = root.getElementsByTagName("MsgType").item(0).getTextContent();
String content = root.getElementsByTagName("Content").item(0).getTextContent();
String msgId = root.getElementsByTagName("MsgId").item(0).getTextContent();
return new Msg(toUserName, fromUserName, createTime, msgType, content, msgId);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private String buildTextResponseXml(Msg msg, String text) {
// 生成回复XML
WxOutTextMessage outMsg = new WxOutTextMessage();
outMsg.setContentType("text");
outMsg.setToUserName(msg.getFromUserName());
outMsg.setFromUserName(msg.getToUserName());
outMsg.setCreateTime(new Date().getTime());
outMsg.setContent(text);
return outMsg.toXml();
}
private String buildImageResponseXml(Msg msg, String mediaId) {
// 生成回复XML
WxOutImageMessage outMsg = new WxOutImageMessage();
outMsg.setContentType("image");
outMsg.setToUserName(msg.getFromUserName());
outMsg.setFromUserName(msg.getToUserName());
outMsg.setCreateTime(new Date().getTime());
outMsg.setMediaId(mediaId);
return outMsg.toXml();
}
}
4.3 回复消息
根据用户发送的消息内容,确定需要回复的消息类型和内容,生成对应类型的消息XML数据。示例中,给出回复文本消息和回复图片消息的代码。
5. 其他功能实现
通过公众号开发者文档,了解微信公众平台提供的其他能力,如自定义菜单、模板消息、微信支付等,并在自己的服务中实现。
示例
示例代码:https://github.com/qianmingzhe/weixin-java-demo
示例1
实现对用户发送的文本信息自动回复。
- 编写一个 Controller,用于处理接收到的消息请求。
@Controller
@RequestMapping("/weixin")
public class WeixinController {
@RequestMapping(method = RequestMethod.GET)
public @ResponseBody String handleGetRequest(@RequestParam(value = "signature") String signature,
@RequestParam(value = "timestamp") String timestamp,
@RequestParam(value = "nonce") String nonce,
@RequestParam(value = "echostr") String echostr) {
if (checkSignature(signature, timestamp, nonce)) {
return echostr;
} else {
return "";
}
}
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody String handlePostRequest(HttpServletRequest request) {
try {
BufferedReader reader = request.getReader();
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
String xml = sb.toString();
requestMsgHandler(xml);
return "";
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
private void requestMsgHandler(String xml) {
XStream xstream = new XStream(new DomDriver());
xstream.alias("xml", RequestMessage.class);
RequestMessage msg = (RequestMessage) xstream.fromXML(xml);
String msgType = msg.getMsgType();
String content = msg.getContent();
if ("text".equals(msgType)) {
String replyXml = buildResponseXml(msg, "你好");
System.out.println(replyXml);
}
}
private String buildResponseXml(RequestMessage request, String content) {
ResponseMessage response = new ResponseMessage();
response.setToUserName(request.getFromUserName());
response.setFromUserName(request.getToUserName());
response.setCreateTime(System.currentTimeMillis());
response.setMsgType("text");
response.setContent(content);
XStream xstream = new XStream(new DomDriver());
xstream.alias("xml", ResponseMessage.class);
return xstream.toXML(response);
}
private boolean checkSignature(String signature, String timestamp, String nonce) {
List<String> fields = Arrays.asList("my_token", timestamp, nonce);
Collections.sort(fields);
String str = StringUtils.join(fields, "");
String hex = DigestUtils.sha1Hex(str);
return hex.equals(signature);
}
}
- 配置菜单功能,用户点击菜单可以直接发送消息给公众号。
示例2
实现用户关注自动回复,关注后推送欢迎语。
- 编写一个 Controller,用于处理接收到的消息请求。
@Controller
@RequestMapping("/weixin")
public class WeixinController {
@RequestMapping(method = RequestMethod.GET)
public @ResponseBody String handleGetRequest(@RequestParam(value = "signature") String signature,
@RequestParam(value = "timestamp") String timestamp,
@RequestParam(value = "nonce") String nonce,
@RequestParam(value = "echostr") String echostr) {
if (checkSignature(signature, timestamp, nonce)) {
return echostr;
} else {
return "";
}
}
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody String handlePostRequest(HttpServletRequest request) {
try {
BufferedReader reader = request.getReader();
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
String xml = sb.toString();
requestMsgHandler(xml);
return "";
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
private void requestMsgHandler(String xml) {
XStream xstream = new XStream(new DomDriver());
xstream.alias("xml", RequestMessage.class);
RequestMessage msg = (RequestMessage) xstream.fromXML(xml);
if ("event".equals(msg.getMsgType()) && "subscribe".equals(msg.getEvent())) {
String replyXml = buildResponseXml(msg, "欢迎关注我的公众号");
System.out.println(replyXml);
}
}
private String buildResponseXml(RequestMessage request, String content) {
ResponseMessage response = new ResponseMessage();
response.setToUserName(request.getFromUserName());
response.setFromUserName(request.getToUserName());
response.setCreateTime(System.currentTimeMillis());
response.setMsgType("text");
response.setContent(content);
XStream xstream = new XStream(new DomDriver());
xstream.alias("xml", ResponseMessage.class);
return xstream.toXML(response);
}
private boolean checkSignature(String signature, String timestamp, String nonce) {
List<String> fields = Arrays.asList("my_token", timestamp, nonce);
Collections.sort(fields);
String str = StringUtils.join(fields, "");
String hex = DigestUtils.sha1Hex(str);
return hex.equals(signature);
}
}
- 配置菜单功能,用户点击菜单可以直接发送消息给公众号。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java版微信公众平台后台接入 - Python技术站