用java怎么做微信公众号,用Java搭建微信公众号(一)构建基础请求框架

最近帮朋友搭建一个微信公众号,通过查看微信公众号的开发者手册把基本功能实现了。把一些基本的可以通用的代码贴出来。

微信公众号提供了两种模式,一种是直接编辑模式,通过操作页面就能搭建基本的功能,比如自定义菜单功能就很好用。一种是开发者模式,需要写代码来搭建,基于HTTP接口(不完全符合REST风格)。比较麻烦的是两种模式是二选一的关系,使用了开发者模式,就得丢弃一些直接编辑的方便。

使用开发者模式的第一步是配置服务器。配置了URL,Token之后,微信服务器会发送一个HTTP GET请求到URL,并附加了signature,timestamp, nonce,echostr这几个参数。只要把echostr原样返回,微信服务器就认为配置成功了。而自己的服务器通过下列规则来判断是否配置成功

1. 把timestamp, nonce, token三个参数排序,然后拼成一个字符串

2. 使用SHA1加密这个字符串

3. 如果加密后的字符串等于signature,那么自己的服务器就可以认为配置成功。

配置的URL对应的控制器相当于一个前端控制器,负责处理微信服务器转发过来的请求。这里注意access_token的作用,如果自己的代码访问微信的HTTP接口,需要在HTTP请求中加入access_token。如果是微信服务器转发过来的请求,那么和access_token没有关系,可以直接处理。微信服务器转发过来的请求就两种,一种是GET,一般只在配置服务器的时候会有。另一种是POST XML的请求,比如用户点击微信公众的菜单,用户在微信公众号中发送的请求等等。

基本的处理微信服务器转发过来的请求代码框架如下

import java.io.InputStream;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

import java.util.Map;

import javax.servlet.ServletInputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import org.springframework.web.servlet.ModelAndView;

import org.w3c.dom.Document;

public class WeixinAPIController extends AbstractBackController {

private static final String token = "1234567890";

@Override

public ModelAndView handleBackRequest(HttpServletRequest request,

HttpServletResponse response, Map model) throws Exception {

boolean isGet = request.getMethod().toLowerCase().equals("get");

if (isGet) {

String echostr = request.getParameter("echostr");

StringBuilder weixinContent = new StringBuilder();

if (checkSignature(request)) {

weixinContent.append(echostr);

} else {

weixinContent.append("Invalid request");

}

response.getWriter().print(weixinContent.toString());

} else {

ServletInputStream in = request.getInputStream();

acceptXML(in, response);

}

response.getWriter().flush();

response.getWriter().close();

return null;

}

private void acceptXML(InputStream in, HttpServletResponse response) throws Exception{

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

try {

DocumentBuilder builder = factory.newDocumentBuilder();

Document doc = builder.parse(in);

String toUserName = doc.getElementsByTagName("ToUserName").item(0).getFirstChild().getNodeValue();

String fromUserName = doc.getElementsByTagName("FromUserName").item(0).getFirstChild().getNodeValue();

String msgType = doc.getElementsByTagName("MsgType").item(0).getFirstChild().getNodeValue();

if("text".equals(msgType)){

String content = doc.getElementsByTagName("Content").item(0).getFirstChild().getNodeValue();

if(content != null && content.length() > 0){

// 接收到微信服务器POST过来的文本信息

// Do something

}

}else if("event".equals(msgType)){

String event = doc.getElementsByTagName("Event").item(0).getFirstChild().getNodeValue();

if("CLICK".equals(event)){

String commandStr = doc.getElementsByTagName("EventKey").item(0).getFirstChild().getNodeValue();

// 接收到微信服务器POST过来的点击菜单信息

// Do something

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

private boolean checkSignature(HttpServletRequest request) {

boolean valid = false;

String signature = request.getParameter("signature");

String timestamp = request.getParameter("timestamp");

String nonce = request.getParameter("nonce");

if (signature == null || timestamp == null || nonce == null) {

return false;

}

List array = new ArrayList();

array.add(token);

array.add(timestamp);

array.add(nonce);

Collections.sort(array);

String tempString = array.get(0) + array.get(1) + array.get(2);

MessageDigest sha1;

try {

sha1 = MessageDigest.getInstance("SHA1");

sha1.update(tempString.getBytes());

byte[] bytes = sha1.digest();

StringBuilder sb = new StringBuilder();

for (int i = 0; i < bytes.length; i++) {

String shaHex = Integer.toHexString(bytes[i] & 0xFF);

if (shaHex.length() < 2) {

sb.append(0);

}

sb.append(shaHex);

}

String encodedToken = sb.toString();

if (encodedToken.equals(signature)) {

valid = true;

}

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

}

return valid;

}

}

当启动服务器配置后,需要等待几分钟才会生效。生效之后就可以接收来自微信服务器转发的消息了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值