这里有新鲜出炉的精品教程,程序狗速度看过来!
Spring是什么呢?首先它是一个开源的项目,而且目前非常活跃;它是一个基于IOC和AOP的构架多层j2ee系统的框架,但它不强迫你必须在每一层 中必须使用Spring,因为它模块化的很好,允许你根据自己的需要选择使用它的某一个模块;它实现了很优雅的MVC,对不同的数据访问技术提供了统一的接口,采用IOC使得可以很容易的实现bean的装配,提供了简洁的AOP并据此实现Transcation Managment,等等
本篇文章主要介绍了JAVA实现 springMVC方式的微信接入、实现消息自动回复,这里整理了详细的代码,有需要的小伙伴可以参考下。
前段时间小忙了一阵,微信公众号的开发,从零开始看文档,踩了不少坑,也算是熬过来了,最近考虑做一些总结,方便以后再开发的时候回顾,也给正在做相关项目的同学做个参考。
1.思路
微信接入:用户消息和开发者需要的事件推送都会通过微信方服务器发起一个请求,转发到你在公众平台配置的服务器url地址,微信方将带上signature,timestamp,nonce,echostr四个参数,我们自己服务器通过拼接公众平台配置的token,以及传上来的timestamp,nonce进行SHA1加密后匹配signature,返回ture说明接入成功。
消息回复:当用户给公众号发送消息时,微信服务器会将用户消息以xml格式通过POST请求到我们配置好的服务器对应的接口,而我们要做的事情就是根据消息类型等做相应的逻辑处理,并将最后的返回结果也通过xml格式return给微信服务器,微信方再传达给用户的这样一个过程。
1.公众平台配置
2.Controller
- @Controller
- @RequestMapping("/wechat")
- publicclass WechatController {
- @Value("${DNBX_TOKEN}")
- private String DNBX_TOKEN;
- private static final Logger LOGGER = LoggerFactory.getLogger(WechatController.class);
- @Resource
- WechatService wechatService;
- /**
- * 微信接入
- * @param wc
- * @return
- * @throws IOException
- */
- @RequestMapping(value="/connect",method = {RequestMethod.GET, RequestMethod.POST})
- @ResponseBody
- publicvoid connectWeixin(HttpServletRequest request, HttpServletResponse response) throws IOException{
- // 将请求、响应的编码均设置为UTF-8(防止中文乱码)
- request.setCharacterEncoding("UTF-8"); //微信服务器POST消息时用的是UTF-8编码,在接收时也要用同样的编码,否则中文会乱码;
- response.setCharacterEncoding("UTF-8"); //在响应消息(回复消息给用户)时,也将编码方式设置为UTF-8,原理同上;boolean isGet = request.getMethod().toLowerCase().equals("get");
- PrintWriter out = response.getWriter();
- try {
- if (isGet) {
- String signature = request.getParameter("signature");// 微信加密签名
- String timestamp = request.getParameter("timestamp");// 时间戳
- String nonce = request.getParameter("nonce");// 随机数
- String echostr = request.getParameter("echostr");//随机字符串
- // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 if (SignUtil.checkSignature(DNBX_TOKEN, signature, timestamp, nonce)) {
- LOGGER.info("Connect the weixin server is successful.");
- response.getWriter().write(echostr);
- } else {
- LOGGER.error("Failed to verify the signature!");
- }
- }else{
- String respMessage = "异常消息!";
- try {
- respMessage = wechatService.weixinPost(request);
- out.write(respMessage);
- LOGGER.info("The request completed successfully");
- LOGGER.info("to weixin server "+respMessage);
- } catch (Exception e) {
- LOGGER.error("Failed to convert the message from weixin!");
- }
- }
- } catch (Exception e) {
- LOGGER.error("Connect the weixin server is error.");
- }finally{
- out.close();
- }
- }
- }
3.签名验证 checkSignature
从上面的controller我们可以看到,我封装了一个工具类SignUtil,调用了里面的一个叫checkSignature,传入了四个值,DNBX_TOKEN, signature, timestamp, nonce。这个过程非常重要,其实我们可以理解为将微信传过来的值进行一个加解密的过程,很多大型的项目所有的接口为保证安全性都会有这样一个验证的过程。DNBX_TOKEN我们在微信公众平台配置的一个token字符串,主意保密哦!其他三个都是微信服务器发送get请求传过来的参数,我们进行一层sha1加密:
- public class SignUtil {
- /**
- * 验证签名
- *
- * @param token 微信服务器token,在env.properties文件中配置的和在开发者中心配置的必须一致
- * @param signature 微信服务器传过来sha1加密的证书签名
- * @param timestamp 时间戳
- * @param nonce 随机数
- * @return
- */
- public static boolean checkSignature(String token,String signature, String timestamp, String nonce) {
- String[] arr = new String[] { token, timestamp, nonce };
- // 将token、timestamp、nonce三个参数进行字典序排序
- Arrays.sort(arr);
- // 将三个参数字符串拼接成一个字符串进行sha1加密
- String tmpStr = SHA1.encode(arr[0] + arr[1] + arr[2]);
- // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
- return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
- }
- }
SHA1:
- /**
- * 微信公众平台(JAVA) SDK
- *
- * SHA1算法
- *
- * @author helijun 2016/06/15 19:49
- */
- public final class SHA1 {
- private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
- '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
- /**
- * Takes the raw bytes from the digest and formats them correct.
- *
- * @param bytes the raw bytes from the digest.
- * @return the formatted bytes.
- */
- private static String getFormattedText(byte[] bytes) {
- int len = bytes.length;
- StringBuilder buf = new StringBuilder(len * 2);
- // 把密文转换成十六进制的字符串形式
- for (int j = 0; j < len; j++) {
- buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
- buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
- }
- return buf.toString();
- }
- public static String encode(String str) {
- if (str == null) {
- return null;
- }
- try {
- MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
- messageDigest.update(str.getBytes());
- return getFormattedText(messageDigest.digest());
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- }
当你在公众平台提交保存,并且看到绿色的提示“接入成功”之后,恭喜你已经完成微信接入。这个过程需要细心一点,注意加密算法里的大小写,如果接入不成功,大多数情况都是加密算法的问题,多检查检查。
4. 实现消息自动回复service
来源: http://www.phperz.com/article/17/1203/359235.html