官方文档
实现代码
service
@Service
public class SysSingnatureWxServiceImpl implements ISysSingnatureWxService {
@Resource
parse2Object parseFormat;
@Autowired
private RedisTemplate<String, String> redisTemplate;
/**
* 获取微信加密信息
* @return
*/
@Override
public JsSdkDto getInfo(){
/** 前端传的 需要授权分享的 url **/
String authorizationUrl = "微信公众平台添加过的域名";
/** 获取微信 access_token 的 url **/
String weChatUrl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
String appId="";// 公众号的 appId
String secret="";// 公众号miyao
String Url= MessageFormat.format(weChatUrl,appId,secret);
String access_token = getToken(Url);
String jsapi_ticket = getTicket(access_token);
return sign(jsapi_ticket, authorizationUrl);
}
/**
* 获取token
* @param url
* @return
*/
public String getToken(String url) {
Map<String, Object> map = null;
Object redisToken = redisTemplate.opsForValue().get("accessToken");
if (redisToken == null) {
try {
HttpClient client = HttpClientBuilder.create().build();//构建一个Client
HttpGet get = new HttpGet(url.toString()); //构建一个GET请求
HttpResponse response = client.execute(get);//提交GET请求
HttpEntity result = response.getEntity();//拿到返回的HttpResponse的"实体"
String content = EntityUtils.toString(result);
JSONObject res = JSONObject.fromObject(content);//把信息封装为json*/
map = parseFormat.parseJSON2Map(content);
// 存储一个小时
redisTemplate.opsForValue().set("accessToken", map.get("access_token").toString(),3600, TimeUnit.HOURS);
} catch (Exception e) {
e.printStackTrace();
}
return map.get("access_token").toString();
} else {
return redisToken.toString();
}
}
/**
* 获取ticket
* @param accessToken
* @return
*/
private String getTicket(String accessToken) {
Object jsapiTicket = redisTemplate.opsForValue().get("jsapiTicket");
String ticket = null;
if (jsapiTicket == null) {
String getTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken
+ "&type=jsapi";
try {
// 获取getTicketResult
HttpClient client = HttpClientBuilder.create().build();//构建一个Client
HttpGet get = new HttpGet(getTicketUrl.toString()); //构建一个GET请求
HttpResponse response = client.execute(get);//提交GET请求
HttpEntity getTicketResult = response.getEntity();//拿到返回的HttpResponse的"实体"
String content = EntityUtils.toString(getTicketResult);
JSONObject ticketResultObject = JSONObject.fromObject(content);//把信息封装为json*/
try {
ticket = (String) ticketResultObject.get("ticket");
} catch (Exception e) {
}
// 缓存中的accessToken可能不是最新的,导致获取ticket失败
// 清除redis缓存的accessToken重新获取 不使用递归避免其他原因获取失败而重复调用
if (ticket == null) {
redisTemplate.delete("accessToken");
return getTicket(accessToken);
}
} catch (Exception e) {
e.printStackTrace();
}
return ticket;
} else {
return jsapiTicket.toString();
}
}
/**
*
* @param jsapi_ticket
* @param url
* @return
*/
public JsSdkDto sign(String jsapi_ticket, String url) {
JsSdkDto jsSdkDto = new JsSdkDto();
Map<String, String> ret = new HashMap<String, String>();
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String string1;
String signature = "";
string1 = new StringBuilder("jsapi_ticket=")
.append(jsapi_ticket)
.append("&noncestr=")
.append(nonce_str)
.append("×tamp=")
.append(timestamp)
.append("&url=")
.append(url)
.toString();
signature = encryptSHA(string1);
jsSdkDto.setNoncestr(nonce_str);
jsSdkDto.setTimestamp(timestamp);
jsSdkDto.setTimeTicket(jsapi_ticket);
jsSdkDto.setSignature(signature);
jsSdkDto.setAppId("wxee315cba6f8b7961");
return jsSdkDto;
}
/**
* create_nonce_str
* @return
*/
private static String create_nonce_str() {
return UUID.randomUUID().toString();
}
/**
* create_timestamp
* @return
*/
private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
/**
* sha
* @param signStr
* @return
*/
private String encryptSHA(String signStr) {
StringBuffer hexValue = new StringBuffer();
MessageDigest sha = null;
try {
sha = MessageDigest.getInstance("SHA-1");
byte[] byteArray = signStr.getBytes("UTF-8");
byte[] md5Bytes = sha.digest(byteArray);
for (int i = 0; i < md5Bytes.length; i++) {
int val = ((int) md5Bytes[i]) & 0xff;
if (val < 16) {
hexValue.append("0");
}
hexValue.append(Integer.toHexString(val));
}
} catch (Exception e) {
e.printStackTrace();
return "";
}
return hexValue.toString();
}
}
parse2Object工具
package com.ruoyi.system.tools;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
public class parse2Object {
/**
* JSON 类型的字符串转换成 Map
*/
@SuppressWarnings("unused")
public static Map<String, Object> parseJSON2Map(String jsonStr) {
Map<String, Object> map = new HashMap<String, Object>();
// 最外层解析
JSONObject json = JSONObject.fromObject(jsonStr);
for (Object k : json.keySet()) {
Object v = json.get(k);
// 如果内层还是数组的话,继续解析
if (v instanceof JSONArray) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
Iterator<JSONObject> it = ((JSONArray) v).iterator();
while (it.hasNext()) {
JSONObject json2 = it.next();
list.add(parseJSON2Map(json2.toString()));
}
map.put(k.toString(), list);
} else {
map.put(k.toString(), v);
}
}
return map;
}
}
验证
打印下生成的签名是否跟官方验证工具中的一致