微信公众号开发
准备工作
你要有一个微信公众号,一个内网穿透工具
相关网站
需要资料
- 服务器配置:设置与开发-->基本配置-->服务器配置
- token:3-32字符,自己生成配置到服务器配置
- 公网 IP:云服务器一般都有公网IP
- 内网穿透工具:本地测试需要穿透,否则无法对接。花生壳、natapp 等自行百度
注意事项
- 请求URL超时,说明内网穿透有问题
- 微信验证消息和推送消息事件接口是同一地址,验证消息是
GET请求 ,事件推送消息是POST。
- 验证成功接口需要给微信原样返回随机字符串(echostr)内容,否则配置失败
- 响应类型(Content-Type) 一定要是
text/plan
- 切记自己对接的系统要是有权鉴,一定要放行微信消息验证接口
代码示例
消息验证
| public void pushGet(HttpServletRequest request, HttpServletResponse response) { |
| String signature = request.getParameter("signature"); |
| String echostr = request.getParameter("echostr"); |
| String timestamp = request.getParameter("timestamp"); |
| String nonce = request.getParameter("nonce"); |
| log.debug("signature:{}", signature); |
| log.debug("echostr:{}", echostr); |
| log.debug("timestamp:{}", timestamp); |
| log.debug("nonce:{}", nonce); |
| System.out.println("signature:" + signature); |
| String sha1 = getSHA1(token, timestamp, nonce); |
| System.out.println("sha1:" + sha1); |
| if (sha1.equals(signature)) { |
| log.debug("成功"); |
| this.responseText(echostr, response); |
| } |
| } |
事件推送
| public void pushPost(HttpServletRequest request, HttpServletResponse response) { |
| String signature = request.getParameter("signature"); |
| String timestamp = request.getParameter("timestamp"); |
| String nonce = request.getParameter("nonce"); |
| String sha1 = getSHA1(token, timestamp, nonce); |
| if (sha1.equals(signature)) { |
| Map map = null; |
| try { |
| map = XmlUtil.parseXMLToMap(request.getInputStream()); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| log.debug("事件消息体:{}", map); |
| |
| this.responseText("", response); |
| } |
| |
| } |
完整代码
| import io.swagger.annotations.Api; |
| import io.swagger.annotations.ApiOperation; |
| import lombok.extern.slf4j.Slf4j; |
| import org.springframework.web.bind.annotation.*; |
| |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.security.MessageDigest; |
| import java.util.*; |
| |
| |
| |
| |
| |
| |
| @Api(tags = "微信配置") |
| @Slf4j |
| @RestController |
| @RequestMapping("/wx/") |
| public class WxController { |
| |
| String token="78******23"; |
| |
| @ApiOperation(value = "微信 token URL 验证") |
| @GetMapping(value = "push") |
| public void pushGet(HttpServletRequest request, HttpServletResponse response) { |
| String signature = request.getParameter("signature"); |
| String echostr = request.getParameter("echostr"); |
| String timestamp = request.getParameter("timestamp"); |
| String nonce = request.getParameter("nonce"); |
| log.debug("signature:{}", signature); |
| log.debug("echostr:{}", echostr); |
| log.debug("timestamp:{}", timestamp); |
| log.debug("nonce:{}", nonce); |
| System.out.println("signature:" + signature); |
| String sha1 = getSHA1(token, timestamp, nonce); |
| System.out.println("sha1:" + sha1); |
| if (sha1.equals(signature)) { |
| log.debug("成功"); |
| this.responseText(echostr, response); |
| } |
| } |
| |
| @ApiOperation(value = "接收微信事件") |
| @PostMapping(value = "push") |
| public void pushPost(HttpServletRequest request, HttpServletResponse response) { |
| String signature = request.getParameter("signature"); |
| String timestamp = request.getParameter("timestamp"); |
| String nonce = request.getParameter("nonce"); |
| String sha1 = getSHA1(token, timestamp, nonce); |
| if (sha1.equals(signature)) { |
| Map map = null; |
| try { |
| |
| map = XmlUtil.parseXMLToMap(request.getInputStream()); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| log.debug("事件消息体:{}", map); |
| |
| this.responseText("", response); |
| } |
| |
| } |
| |
| |
| |
| |
| |
| |
| |
| public void responseText(String text, HttpServletResponse response) { |
| response.setCharacterEncoding("UTF-8"); |
| response.setContentType("text/plan;charset=UTF-8"); |
| PrintWriter writer = null; |
| try { |
| writer = response.getWriter(); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| writer.write(text); |
| writer.flush(); |
| writer.close(); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public String getSHA1(String token, String timestamp, String nonce) { |
| try { |
| String[] array = new String[]{token, timestamp, nonce}; |
| StringBuffer sb = new StringBuffer(); |
| |
| Arrays.sort(array); |
| for (int i = 0; i < 3; i++) { |
| sb.append(array[i]); |
| } |
| String str = sb.toString(); |
| |
| MessageDigest md = MessageDigest.getInstance("SHA-1"); |
| md.update(str.getBytes()); |
| byte[] digest = md.digest(); |
| |
| StringBuffer hexstr = new StringBuffer(); |
| String shaHex = ""; |
| for (int i = 0; i < digest.length; i++) { |
| shaHex = Integer.toHexString(digest[i] & 0xFF); |
| if (shaHex.length() < 2) { |
| hexstr.append(0); |
| } |
| hexstr.append(shaHex); |
| } |
| return hexstr.toString(); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| return null; |
| } |
| |
| } |
| |
响应结果
消息验证
| signature:207e05105427e1203e769245b3860212c0ffcc56 |
| echostr:5692172970033782203 |
| timestamp:1685068850 |
| nonce:499790541 |
| signature:207e05105427e1203e769245b3860212c0ffcc56 |
| sha1:207e05105427e1203e769245b3860212c0ffcc56 |
| 成功 |
事件推送
打开公众号发送消息,接口就可以获取到推送事件消息内容了
| {"Content":"嘻嘻嘻","CreateTime":"1685068967","ToUserName":"gh_2121212a95","FromUserName":"333333333nSg8OlaSuB0d-f8FKZo","MsgType":"text","MsgId":"24124387253374797"} |
其他信息
公众号配置

内网穿透
