一、根據(jù)微信公眾號(hào)開(kāi)發(fā)文檔編寫(xiě)的驗(yàn)證方法,寫(xiě)在util包中。
1、首先在util包下創(chuàng)建SignUtil類
package com.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public class SignUtil {
// 與接口配置信息中的Token要一致
private static String token = "weixinmp";
/**
* 驗(yàn)證簽名
*
* @param signature
* @param timestamp
* @param nonce
* @return
*/
public static boolean checkSignature(String signature, String timestamp, String nonce) {
String[] arr = new String[] { token, timestamp, nonce };
// 將token、timestamp、nonce三個(gè)參數(shù)進(jìn)行字典序排序
Arrays.sort(arr);
StringBuilder content = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
content.append(arr[i]);
}
MessageDigest md = null;
String tmpStr = null;
try {
md = MessageDigest.getInstance("SHA-1");
// 將三個(gè)參數(shù)字符串拼接成一個(gè)字符串進(jìn)行sha1加密
byte[] digest = md.digest(content.toString().getBytes());
tmpStr = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
content = null;
// 將sha1加密后的字符串可與signature對(duì)比,標(biāo)識(shí)該請(qǐng)求來(lái)源于微信
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
}
/**
* 將字節(jié)數(shù)組轉(zhuǎn)換為十六進(jìn)制字符串
*
* @param byteArray
* @return
*/
private static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
* 將字節(jié)轉(zhuǎn)換為十六進(jìn)制字符串
*
* @param mByte
* @return
*/
private static String byteToHexStr(byte mByte) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
char[] tempArr = new char[2];
tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
tempArr[1] = Digit[mByte & 0X0F];
String s = new String(tempArr);
return s;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
2、在controller包下創(chuàng)建核心控制類CoreController
package com.controller;
import com.util.SignUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("")
public class CoreController {
//增加日志
private static Logger log = LoggerFactory.getLogger(CoreController.class);
//驗(yàn)證是否來(lái)自微信服務(wù)器的消息
@RequestMapping(value = "",method = RequestMethod.GET)
public String checkSignature(@RequestParam(name = "signature" ,required = false) String signature ,
@RequestParam(name = "nonce",required = false) String nonce ,
@RequestParam(name = "timestamp",required = false) String timestamp ,
@RequestParam(name = "echostr",required = false) String echostr){
// 通過(guò)檢驗(yàn)signature對(duì)請(qǐng)求進(jìn)行校驗(yàn),若校驗(yàn)成功則原樣返回echostr,表示接入成功,否則接入失敗
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
log.info("接入成功");
return echostr;
}
log.error("接入失敗");
return "";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
注意
2、接下來(lái)設(shè)置微信公眾號(hào)開(kāi)發(fā)的url和token
url必須是外網(wǎng)地址(我是通過(guò)ngrok來(lái)創(chuàng)建一個(gè)外網(wǎng)地址映射到本地地址,可以搜索下ngrok的使用方法)。
設(shè)置完成后,run項(xiàng)目,然后再點(diǎn)擊公眾號(hào)的接口配置信息的提交,成功的話就顯示配置成功,否則顯示失敗。(有時(shí)候微信大姨媽,第一次總是配置失敗<不知道是ngrok的問(wèn)題不>,要點(diǎn)擊2次才配置成功。)
二、消息的處理
1、在service包中創(chuàng)建一個(gè)core包,在core包中創(chuàng)建接口類CoreService和實(shí)現(xiàn)類CoreServiceImpl(這里你也可以不用創(chuàng)建core包,直接在service包中建這兩個(gè)類,我這是為了后期的維護(hù)便利而已。)
CoreService.java
package com.service.core;
import javax.servlet.http.HttpServletRequest;
/**
* Created by Administrator on 2016/11/8.
*/
public interface CoreService {
public String processRequest(HttpServletRequest request) ;
}
CoreServiceImpl.java
/**
* 核心服務(wù)類
*/
@Service("coreService")
public class CoreServiceImpl implements CoreService {
private static Logger log = LoggerFactory.getLogger(CoreServiceImpl.class);
/**
* 處理微信發(fā)來(lái)的請(qǐng)求(包括事件的推送)
*
* @param request
* @return
*/
public String processRequest(HttpServletRequest request) {
//暫時(shí)對(duì)消息不作處理
return "";
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
3、再在Corecontroller類中加入、對(duì)消息的處理方法,我給出完整類
package com.controller;
import com.service.core.CoreService;
import com.util.SignUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("")
public class CoreController {
@Autowired
private CoreService coreService;
//增加日志
private static Logger log = LoggerFactory.getLogger(CoreController.class);
//驗(yàn)證是否來(lái)自微信服務(wù)器的消息
@RequestMapping(value = "",method = RequestMethod.GET)
public String checkSignature(@RequestParam(name = "signature" ,required = false) String signature ,
@RequestParam(name = "nonce",required = false) String nonce ,
@RequestParam(name = "timestamp",required = false) String timestamp ,
@RequestParam(name = "echostr",required = false) String echostr){
// 通過(guò)檢驗(yàn)signature對(duì)請(qǐng)求進(jìn)行校驗(yàn),若校驗(yàn)成功則原樣返回echostr,表示接入成功,否則接入失敗
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
log.info("接入成功");
return echostr;
}
log.error("接入失敗");
return "";
}
// 調(diào)用核心業(yè)務(wù)類接收消息、處理消息跟推送消息
@RequestMapping(value = "",method = RequestMethod.POST)
public String post(HttpServletRequest req){
String respMessage = coreService.processRequest(req);
return respMessage;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
由于時(shí)間問(wèn)題,暫時(shí)寫(xiě)到這里,下一篇講對(duì)消息的接收與回復(fù)。
|