当前位置:   article > 正文

JAVA源码微信公众号开发 | 第一篇: 前期准备及实现自动回复(附源码)

公众号自动回复 java对 源码

JAVA微信公众号开发 | 第一篇: 前期准备及实现自动回复(附源码)

本系列文章是记录自己微信公众号的开发过程,也希望能为感兴趣的其他人提供一些思路和帮助
欢迎转发,转发请在文前明显位置,注明本文地址
项目源码放到文末,需要自取
最终效果
1558849-20190706151248989-723684306.jpg

前言

有一个特别坑的地方,需要提前说一下 个人订阅号 现在已经没有接口开发自定义菜单的权限了。
1558849-20190706151348757-824874173.png

也就是说只能通过微信账号后台自定义菜单,而不能通过接口开发自定义菜单
但是接口开发和后台自定义两者互斥
1558849-20190706151358256-1308968720.png
要想接口开发自定义菜单,就必须是认证公众号,但是
1558849-20190706151527762-976042234.png

wt fk
鸡你太美 诶,,,
鸡你太美**
但是服务号申请也不难
虽然有这么多限制,我还是想去尝试一下,兴趣大于一切

1.申请公众号

  • 登录地址:https://mp.weixin.qq.com/,注册-选择类型,
  • 对类型不清楚的点击链接,账号类型区别http://kf.qq.com/faq/170815aUZjeQ170815mU7bI7.html
  • 公众号申请流程:http://kf.qq.com/product/weixinmp.html#hid=99

申请服务号 还是比较麻烦的 但是服务号是直接展示在好友消息列表中 而订阅号是展示在订阅号消息
1558849-20190706151538894-1454143198.png

2.云服务器或者其他外网映射工具

我用的是腾讯云。其他外网映射工具在这里就不说了,搜一下很多

3.接口配置

进入配置页面:基本配置 > 修改配置
1558849-20190706151545062-107181702.png

  • URL:中的IP地址,如果是腾讯云则可以在云服务器界面找自己的公网IP地址
  • Token :可以自己随意填,但是要和后面服务器的保持一致
    1558849-20190706151553288-1592176684.png

点击提交>确定
之后微信会自动向你的服务器发送GET请求并验证你的服务器,因此我们需要完成了对GET请求的处理(后面有代码讲解,先不用点确定)

4.验证消息的确来自微信服务器

开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:

参数描述
signature微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数
timestamp时间戳
nonce随机数
echostr随机字符串

开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则> 接入生效,成为开发者成功,否则接入失败。
加密/校验流程如下:
1)将token、timestamp、nonce三个参数进行字典序排序
2)将三个参数字符串拼接成一个字符串进行sha1加密
3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

以上是来源 微信文档,写的很清楚了,撸代码。

  1. /**
  2. * 处理微信服务器发来的get请求,进行签名的验证
  3. * signature 微信端发来的签名 * timestamp 微信端发来的时间戳
  4. * nonce     微信端发来的随机字符串
  5. * echostr   微信端发来的验证字符串
  6. */
  7. @GetMapping(value = "wechat")
  8. public String validate(@RequestParam(value = "signature") String signature,        
  9. @RequestParam(value = "timestamp") String timestamp,                     
  10. @RequestParam(value = "nonce") String nonce,                      
  11. @RequestParam(value = "echostr") String echostr) {   
  12. return WeChatUtil.checkSignature(signature, timestamp, nonce) ? echostr : null;
  13. }
  1. public static boolean checkSignature(String signature, String timestamp, String nonce) {   
  2. String[] arr = new String[] { WeChatContant.TOKEN, timestamp, nonce };   
  3. // 将token、timestamp、nonce三个参数进行字典序排序   
  4. sort(arr);   
  5. StringBuilder content = new StringBuilder();   
  6. for (int i = 0; i < arr.length; i++) {       
  7. content.append(arr[i]);   
  8. }   
  9. MessageDigest md = null;   
  10. String tmpStr = null;   
  11. try {       
  12. md = MessageDigest.getInstance("SHA-1");       
  13. // 将三个参数字符串拼接成一个字符串进行sha1加密       
  14. byte[] digest = md.digest(content.toString().getBytes());       
  15. tmpStr = byteToStr(digest);   
  16. } catch (NoSuchAlgorithmException e) {       
  17. e.printStackTrace();   
  18. }   
  19. content = null;   
  20. // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信   
  21. return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
  22. }

String[] arr = new String[] { WeChatContant.TOKEN, timestamp, nonce };
此处的WeChatContant.TOKEN是个常量 public static final String TOKEN = "lhx";
必须和上文基本配置中的 此处随便写 保持一致
完成之后 把项目打个JAR包 扔到服务器上面(别忘安装jdk,安装方法百度搜一下)
此处用到的工具软件:Xshell 6 Xftp 6
工具软件放到文末,需要自取

  1. <build>   
  2. <plugins>       
  3. <plugin>           
  4. <groupId>org.springframework.boot</groupId>           
  5. <artifactId>spring-boot-maven-plugin</artifactId>           
  6. <executions>               
  7. <execution>                   
  8. <configuration>         
  9. <!--此处填写boot启动类-->              
  10. <mainClass>com.lhx.wechat.WechatApplication</mainClass>          
  11. </configuration>                 
  12. <goals>                       
  13. <goal>repackage</goal>        
  14. </goals>      
  15. </execution>           
  16. </executions>       
  17. </plugin>   
  18. </plugins>
  19. </build>

项目源码中添加了maven打包插件 可以直接maven clen package -> 可运行的jar包
项目源码放到文末,需要自取

然后再回到 配置页面:基本配置 > 修改配置 > 提交 >确定 网页顶端会显示提交成功
1558849-20190706151617335-1480860921.png

5.接收普通消息

当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。
请注意:
1、关于重试的消息排重,推荐使用msgid排重。
2、微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接 回复空串,微信服务器不会对此作任何处理,并且不会发起重试。详情请见“发送消息-被动回复消息”。
3、如果开发者需要对用户消息在5秒内立即做出回应,即使用“发送消息-被动回复消息”接口向用户被动回复消息时,可以在公众平台官网的开发者中心处设置消息加密。开启加密后,用户发来的消息和开发者回复的消息都会被加密(但开发者通过客服接口等API调用形式向用户发送消息,则不受影响)。关于消息加解密的详细说明,请见“发送消息-被动回复消息加解密说明”。各消息类型的推送XML数据包结构如下:

  1. <xml>
  2. <ToUserName><![CDATA[toUser]]></ToUserName>
  3. <FromUserName><![CDATA[fromUser]]></FromUserName>
  4. <CreateTime>1348831860</CreateTime>
  5. <MsgType><![CDATA[text]]></MsgType>
  6. <Content><![CDATA[this is a test]]></Content>
  7. <MsgId>1234567890123456</MsgId>
  8. </xml>
参数描述
ToUserName开发者微信号
FromUserName发送方帐号(一个OpenID)
CreateTime消息创建时间 (整型)
MsgType消息类型,文本为text
Content文本消息内容
MsgId消息id,64位整型

文末有源码

6.回复普通消息

当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特> 定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。严格来说,发送被动响应消息其实并不是一种> 接口,而是对微信服务器发过来消息的一次回复。需要的XML数据包结构如下:

回复文本消息

  1. <xml>
  2. <ToUserName><![CDATA[toUser]]></ToUserName>
  3. <FromUserName><![CDATA[fromUser]]></FromUserName>
  4. <CreateTime>12345678</CreateTime>
  5. <MsgType><![CDATA[text]]></MsgType>
  6. <Content><![CDATA[你好]]></Content>
  7. </xml>
参数是否必须描述
ToUserName接收方帐号(收到的OpenID)
FromUserName开发者微信号
CreateTime消息创建时间 (整型)
MsgType消息类型,文本为text
Content回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)

文末有源码

完整代码

  1. @PostMapping(value = "wechat")
  2. public String textMessge(HttpServletRequest request) {   
  3. logger.info("wechat"); 
  4. return javaMessageService.textMessage(request);
  5. }
  1. @Service
  2. public class JavaMessageServiceImpl implements JavaMessageService {   
  3. private static final Logger logger = LoggerFactory.getLogger(JavaMessageServiceImpl.class);   
  4. @Override   
  5. public String textMessage(HttpServletRequest request) {       
  6. logger.info("进来了");      
  7. // xml格式的消息数据       
  8. String respXml = null;      
  9. // 默认返回的文本消息内容       
  10. String respContent;       
  11. try {        
  12. // 调用parseXml方法解析请求消息     
  13. Map<String,String> requestMap = WeChatUtil.parseXml(request);     
  14. // 消息类型         
  15. String msgType = requestMap.get(WeChatContant.MsgType);       
  16. String mes = null;        
  17. // 文本消息          
  18. if (msgType.equals(WeChatContant.REQ_MESSAGE_TYPE_TEXT)) {         
  19. mes =requestMap.get(WeChatContant.Content);              
  20. if(mes != null){                  
  21. String content = checkResources(mes);              
  22. if(!StringUtils.isBlank(content)) {                   
  23. return WeChatUtil.sendTextMsg(requestMap, content);                
  24. }           
  25. }          
  26. }           
  27. // 图片消息           
  28. // ......           
  29. mes = mes == null ? "在吗" : mes;         
  30. return WeChatUtil.sendTextMsg(requestMap, mes);   
  31. } catch (DocumentException e) {      
  32. return null;       
  33. } catch (Exception e) {         
  34. e.printStackTrace();   
  35. return null;   
  36. }      
  37. return null;   
  38. }   
  39. private String checkResources(String message){       
  40. String returnMessage = null;       
  41. if("加油".equals(message)){           
  42. returnMessage = "你也是";           
  43. return returnMessage;       
  44. }       
  45. if("我爱你".equals(message)){           
  46. returnMessage = "一见面就说爱?";           
  47. return returnMessage;       
  48. }       
  49. return null;   
  50. }
  51. }

测试可以用postman 进行测试

项目源码和本文用到的所有工具我已经打包好放在了微信公众号中> "爪哇之父兄弟",
关注后,回复"公众号源码",即可获取
如果你对本文有不对的地方或者遇到难题了 欢迎评论或者扫码进群 一起讨论 免费帮助
如果本文对你有帮助,请小编喝咖啡啊

公众号 爪哇之父兄弟微信支付宝q群
1558849-20190706151635293-1817786990.jpg1558849-20190706151644183-1555520280.png1558849-20190706151651772-569125660.png1558849-20190706151658474-1688173612.png

转载于:https://www.cnblogs.com/doagain/p/11142874.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/341482
推荐阅读
相关标签
  

闽ICP备14008679号