packagecom.test.cms.share;importcn.hutool.json.JSONUtil;importorg.apache.commons.lang.StringUtils;importorg.apache.http.HttpEntity;importorg.apache.http.HttpResponse;importorg.apache.http.StatusLine;importorg.apache.http.client.ClientProtocolException;importorg.apache.http.client.HttpClient;importorg.apache.http.client.HttpResponseException;importorg.apache.http.client.ResponseHandler;importorg.apache.http.client.methods.HttpGet;importorg.apache.http.conn.ssl.SSLConnectionSocketFactory;importorg.apache.http.impl.client.CloseableHttpClient;importorg.apache.http.impl.client.HttpClientBuilder;importorg.apache.http.impl.client.HttpClients;importorg.apache.http.util.EntityUtils;importorg.json.JSONException;importorg.json.JSONObject;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.ResponseBody;importjavax.net.ssl.SSLContext;importjavax.net.ssl.TrustManager;importjavax.net.ssl.X509TrustManager;importjava.io.IOException;importjava.net.URI;importjava.security.cert.CertificateException;importjava.security.cert.X509Certificate;importjava.util.HashMap;importjava.util.Map;
@Controllerpublic classShareController {/*** 微信公众号的appid*/
private String appid="wxd";/*** 微信公众号的appSecret*/
private String secret="ebded33";/*** 这是跳转到分享的页面
*@return
*/@RequestMapping(value= "/to_detail")publicString share(){return "/index/share";
}/*** 获取微信分享配置的请求 方法只写了主要方法,需要根据自己的要求 完善代码
*@paramurl 前台传过来的当前页面的请求地址
*@return
*/@RequestMapping(value= "/get_wx_config")
@ResponseBodypublicString share(String url){long timestamp = System.currentTimeMillis() / 1000;
String noncestr= RandomStr.createRandomString(16);
String ticket=getJsapiTicket();
String str= "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" +url;
System.out.println("签名str:" +str);
String signature=Sha1.encode(str);//这只是简单写法,没有做错误判断
Map map=newHashMap();
map.put("appId",appid);
map.put("timestamp",timestamp);
map.put("nonceStr",noncestr);
map.put("signature",signature);//这里使用了hutool工具将map转为String
String json =JSONUtil.toJsonStr(map);returnjson;
}/*** 官方文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62
*
* 获取jsapi_ticket
*
*
* 生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。
* 正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。
* 由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。
*
* 参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):
*https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html*
* 用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):
*https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
*
*@return
*/
publicString getJsapiTicket() {
String tokenUrl= "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
tokenUrl= tokenUrl + "&appid=" + appid + "&secret=" +secret;
JSONObject tokenJson=newJSONObject();
tokenJson=getUrlResponse(tokenUrl);
System.out.println("tokenJson:"+tokenJson.toString());
String token="";try{
token=tokenJson.getString("access_token");
}catch(JSONException e) {
e.printStackTrace();
System.out.println("报错了");return null;
}
String jsapiTicketUrl="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
JSONObject jsapiTickeJson=newJSONObject();
System.out.println("getJsapiTicket:获取token:"+token);if(StringUtils.isNotBlank(token)){
jsapiTicketUrl= jsapiTicketUrl.replace("ACCESS_TOKEN",token);
jsapiTickeJson=getUrlResponse(jsapiTicketUrl);
System.out.println("tokenJson:"+jsapiTickeJson.toString());try{return (String) jsapiTickeJson.get("ticket");
}catch(JSONException e) {
e.printStackTrace();return null;
}
}else{return null;
}
}privateJSONObject getUrlResponse(String url){
CharsetHandler handler= new CharsetHandler("UTF-8");try{
HttpGet httpget= new HttpGet(newURI(url));
HttpClientBuilder httpClientBuilder=HttpClientBuilder.create();//HttpClient
CloseableHttpClient client =httpClientBuilder.build();
client=(CloseableHttpClient) wrapClient(client);return newJSONObject(client.execute(httpget, handler));
}catch(Exception e) {
e.printStackTrace();return null;
}
}private staticHttpClient wrapClient(HttpClient base) {try{
SSLContext ctx= SSLContext.getInstance("TLSv1");
X509TrustManager tm= newX509TrustManager() {public voidcheckClientTrusted(X509Certificate[] xcs,
String string)throwsCertificateException {
}public voidcheckServerTrusted(X509Certificate[] xcs,
String string)throwsCertificateException {
}publicX509Certificate[] getAcceptedIssuers() {return null;
}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLConnectionSocketFactory sslsf= new SSLConnectionSocketFactory(ctx, new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient=HttpClients.custom().setSSLSocketFactory(sslsf).build();returnhttpclient;
}catch(Exception ex) {return null;
}
}private class CharsetHandler implements ResponseHandler{privateString charset;publicCharsetHandler(String charset) {this.charset =charset;
}publicString handleResponse(HttpResponse response)throwsClientProtocolException, IOException {
StatusLine statusLine=response.getStatusLine();if (statusLine.getStatusCode() >= 300) {throw newHttpResponseException(statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
HttpEntity entity=response.getEntity();if (entity != null) {if (!StringUtils.isBlank(charset)) {returnEntityUtils.toString(entity, charset);
}else{returnEntityUtils.toString(entity);
}
}else{return null;
}
}
}
}