package com.runmin.bajie.entity;
/**
* 凭证
*
*/
public class Token {
// 接口访问凭证
private String accessToken;
// 凭证有效期,单位:秒
private int expiresIn;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}
}
package com.runmin.bajie.entity;
public class JsapiTicket {
// 获取到的凭证
private String ticket;
// 凭证有效期,单位:秒
private int expiresIn;
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}
}
package com.runmin.bajie.util;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import com.runmin.bajie.entity.JsapiTicket;
import com.runmin.bajie.entity.Token;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
public class TokenUtil {
public final static String appid = "***********************************";
public final static String secret = "***********************************";
// 凭证获取(GET),token_url获取凭证接口的请求地址
public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?"
+ "grant_type=client_credential&"
+ "appid=" + appid + "&"
+ "secret=" + secret;
/**
* 发送https请求.定义了一个通用的HTTPS请求方法,用于发送HTTPS GET和POST请求
* 当调用公众平台的开发接口时,都需要传入接口访问凭证access_token
*
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return
*/
public static JSONObject getTokenJsonObject(String requestUrl, String requestMethod, String outputStr){
JSONObject returnData = null;
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = {new MyX509TrustManager()};
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(GET/POST)
conn.setRequestMethod(requestMethod);
// 当outputStr不为null时向输出流写数据
if (null != outputStr) {
OutputStream outputStream = conn.getOutputStream();
// 注意编码格式
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 从输入流读取返回内容
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
// 释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
returnData = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
System.out.printf("连接超时:{}", ce);
} catch (Exception e) {
System.out.printf("https请求异常:{}", e);
}
return returnData;
}
/**
* 获取接口访问凭证。将得到的json结果转为Token对象
* @return
*/
public static Token getToken(){
Token token = null;
String requestUrl = token_url;
// 发起GET请求获取凭证
JSONObject returnData = getTokenJsonObject(requestUrl, "GET", null);
if(null != returnData){
try {
token = new Token();
token.setAccessToken(returnData.getString("access_token"));
token.setExpiresIn(Integer.parseInt(returnData.getString("expires_in")));
} catch (Exception e) {
token = null;
// 获取token失败
System.out.printf("获取token失败 errcode:{} errmsg:{}", returnData.get("errcode"),
returnData.get("errmsg"));
}
}
return token;
}
/**
* 获取jsapi_ticket
*
* @param appid 凭证
* @param appsecret 密钥
* @return
*/
public static JsapiTicket getJsapiTicket(String accessToken) {
//获取公众号jsapi_ticket的链接
String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?"
+ "access_token=ACCESS_TOKEN&type=jsapi";
//ticket分享值
JsapiTicket jsapiticket = null;
if(accessToken != null){
String requestUrl = jsapi_ticket_url.replace("ACCESS_TOKEN", accessToken);
JSONObject jsonObject = getTokenJsonObject(requestUrl, "GET", null);
// 如果请求成功
if (null != jsonObject) {
try {
jsapiticket = new JsapiTicket();
jsapiticket.setTicket(jsonObject.getString("ticket"));
jsapiticket.setExpiresIn(jsonObject.getInt("expires_in"));
} catch (JSONException e) {
jsapiticket = null;
// 获取ticket失败
System.out.printf("获取ticket失败 errcode:{} errmsg:{}",
jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
}
}
}else{
System.out.println("*****token为空 获取ticket失败******");
}
return jsapiticket;
}
}
package com.runmin.bajie.util;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
public class MyX509TrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException
{
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException
{
}
public X509Certificate[] getAcceptedIssuers()
{
return null;
}
}
package com.runmin.bajie.util;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 官方给的使用js的验证工具
*
*/
public class JsSignUtil {
public static String accessToken = null;
public static Map<String, String> sign(String url) {
// 获取accessToken
accessToken = TokenUtil.getToken().getAccessToken();
// 获取JsapiTicket
String jsapi_ticket = TokenUtil.getJsapiTicket(accessToken).getTicket();
Map<String, String> ret = new HashMap<String, String>();
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String string1;
String signature = "";
// 注意这里参数名必须全部小写,且必须有序
string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "×tamp=" + timestamp + "&url=" + url;try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
ret.put("appId", "wxd3bda909c7fb1467");
return ret;
}
/**
* 随机加密
*
* @param hash
* @return
*/
private static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
/**
* 产生随机串--由程序自己随机产生
*
* @return
*/
private static String create_nonce_str() {
return UUID.randomUUID().toString();
}
/**
* 由程序自己获取当前时间
*
* @return
*/
private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
}
package com.runmin.bajie.web;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.runmin.bajie.util.JsSignUtil;
@Controller
public class WeixinScanController {
/**
* 微信扫一扫接口的后台处理程序
*
* @param request
* @param response
* @return
* @throws Exception
*/
@RequestMapping(value = "/weixinScan")
@ResponseBody
public Object weixinScan(HttpServletRequest request, HttpServletResponse response) throws Exception {
String weburl = request.getParameter("url");
Map<String, String> resMap = new HashMap<String, String>();
resMap = JsSignUtil.sign(weburl);
return resMap;
}
}