1:WeixinUtil.java
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.google.gson.Gson;
import com.szmsd.entity.AccessAuthor;
import com.szmsd.entity.AccessTicket;
import com.szmsd.entity.AccessToken;
import com.szmsd.platform.constants.Constants;
import com.szmsd.platform.util.MyX509TrustManager;
public class WeixinUtil {
private static Log logger = LogFactory.getLog(WeixinUtil.class);
// 根据授权获取的code得到openid
public final static String access_openid_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code";
// 获取access_token的接口地址(GET) 限200(次/天)
public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
// 获取access_ticket的接口地址(GET) 限200(次/天)
public final static String access_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
/**
* 发起https请求并获取结果
*
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
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 httpUrlConn = (HttpsURLConnection) url
.openConnection();
httpUrlConn.setSSLSocketFactory(ssf);
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
// 设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod)) {
httpUrlConn.connect();
}
// 当有数据需要提交时
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 将返回的输入流转换成字符串
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
logger.error("Weixin server connection timed out.");
} catch (Exception e) {
logger.error("https request error:{}", e);
}
return jsonObject;
}
/**
* 获取用户openid
* @param appid
* @param appsecret
* @param code
* @return
*/
public static AccessAuthor getAccessAuthor(String appid, String appsecret,String code){
AccessAuthor accessAuthor = null;
String requestUrl = access_openid_url.replace("APPID", appid).replace("APPSECRET", appsecret).replace("CODE", code);
JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
// 如果请求成功
if (null != jsonObject) {
try {
accessAuthor = new AccessAuthor();
accessAuthor.setOpenid(jsonObject.getString("openid"));
accessAuthor.setRefresh_token(jsonObject.getString("refresh_token"));
accessAuthor.setScope(jsonObject.getString("scope"));
accessAuthor.setAccess_token(jsonObject.getString("access_token"));
} catch (Exception e) {
// TODO: handle exception
accessAuthor = null;
// 获取token失败
logger.info("获取用户openid异常"+e.getMessage());
}
}
return accessAuthor;
}
/**
* 获取access_token
*
* @param appid 凭证
* @param appsecret 密钥
* @return
*/
public static AccessToken getAccessToken(String appid, String appsecret) {
AccessToken accessToken = null;
accessToken = (AccessToken) Constants.global_map.get("accessToken");
if(accessToken == null){
String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
// 如果请求成功
if (null != jsonObject) {
try {
accessToken = new AccessToken();
accessToken.setToken(jsonObject.getString("access_token"));
accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
Constants.global_map.put("accessToken", accessToken);
logger.debug("获取accessToken:" + new Gson().toJson(accessToken));
} catch (JSONException e) {
accessToken = null;
// 获取token失败
logger.error("获取token失败 errcode:{} errmsg:{}");
}
}
} else {
logger.debug("获取accessToken:" + new Gson().toJson(accessToken));
}
return accessToken;
}
/**
* 获取access_ticket
* @param token
* @return
*/
public static AccessTicket getAccessTicket(String token){
AccessTicket accessTicket = null;
String requestUrl = access_ticket_url.replace("ACCESS_TOKEN", token);
JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
logger.info(""+jsonObject);
// 如果请求成功
if (null != jsonObject) {
try {
accessTicket = new AccessTicket();
accessTicket.setErrcode(jsonObject.getString("errcode"));
accessTicket.setErrmsg(jsonObject.getString("errmsg"));
accessTicket.setTicket(jsonObject.getString("ticket"));
accessTicket.setExpires_in(jsonObject.getString("expires_in"));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
accessTicket = null;
// 获取ticket失败
logger.info("获取ticket失败 errcode:{} errmsg:{}");
}
}
return accessTicket;
}
public static Map<String, String> sign(String jsapi_ticket, String url) {
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;
logger.info("string1===>" + string1);
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);
return ret;
}
/**
* 随机字符串
* @return
*/
private static String create_nonce_str() {
return UUID.randomUUID().toString();
}
/**
* 时间戳
* @return
*/
private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
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;
}
}
2:AccessToken.java
public class AccessToken {
// 获取到的凭证
private String token;
// 凭证有效时间,单位:秒
private int expiresIn;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}
}
3:AccessTicket.java
public class AccessTicket {
private String errcode;
private String errmsg;
private String ticket;
private String expires_in;
public String getErrcode() {
return errcode;
}
public void setErrcode(String errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public String getExpires_in() {
return expires_in;
}
public void setExpires_in(String expires_in) {
this.expires_in = expires_in;
}
}
4:AccessAuthor.java
public class AccessAuthor {
private String access_token;
private String expires_in;
private String refresh_token;
private String openid;
private String scope;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getExpires_in() {
return expires_in;
}
public void setExpires_in(String expires_in) {
this.expires_in = expires_in;
}
public String getRefresh_token() {
return refresh_token;
}
public void setRefresh_token(String refresh_token) {
this.refresh_token = refresh_token;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
}
5:WechatHandle.java
public class WechatHandle extends BaseAction {
private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(WechatHandle.class);
private String appid = Constants.APPID;
private String appsecret = Constants.APPSECRET;
/**
* 获取用户微信openid
* @throws Exception
*/
public void accessUserOpenid() throws Exception{
AccessAuthor accessAuthor = null;
try {
String code = req().getParameter("code");
log.info("【获取js配置信息】请求参数:code:"+code);
accessAuthor = WeixinUtil.getAccessAuthor(appid, appsecret, code);
if(accessAuthor!=null){
resJson.setSuccess(true);
resJson.setData(accessAuthor);
resJson.setDesc("请求成功!");
session().setAttribute("sessionOpenId", accessAuthor.getOpenid());
} else {
resJson.setSuccess(false);
resJson.setDesc("获取用户微信openid失败!");
}
} catch (Exception e) {
resJson.setSuccess(false);
resJson.setDesc("获取用户微信openid失败!");
log.error("获取用户微信openid...异常===>"+e.getMessage());
}
String result = new Gson().toJson(resJson);
log.info("【获取用户微信openid】请求结果===>"+result);
out().print(result);
}
/**
* 获取js配置信息
* @throws Exception
*/
@SuppressWarnings("rawtypes")
public void accessJsConfig() throws Exception{
JsConfig jsConfig = new JsConfig();
jsConfig.setAppid(appid);
String url = req().getParameter("dynamicurl");
log.debug("【获取js配置信息】请求参数:appid:"+appid+"~appsecret:"+appsecret+"~dynamicurl"+url);
try {
// 获取access_token
AccessToken accessToken = WeixinUtil.getAccessToken(appid,appsecret);
// 获取access_ticket
AccessTicket accessTicket = WeixinUtil.getAccessTicket(accessToken.getToken());
Map<String, String> ret = WeixinUtil.sign(accessTicket.getTicket(), url);
for (Map.Entry entry : ret.entrySet()) {
String key = entry.getKey().toString();
String value = entry.getValue().toString();
if("timestamp".equals(key)){
jsConfig.setTimestamp(value);
} else if("nonceStr".equals(key)){
jsConfig.setNonceStr(value);
} else if("jsapi_ticket".equals(key)){
jsConfig.setJsapi_ticket(value);
} else if("signature".equals(key)){
jsConfig.setSignature(value);
} else if("url".equals(key)){
jsConfig.setUrl(value);
}
}
} catch (Exception e) {
// TODO: handle exception
log.error("获取js配置信息...异常===>"+e.getMessage());
Constants.global_map.clear();
AccessToken accessToken = WeixinUtil.getAccessToken(appid,appsecret);
AccessTicket accessTicket = WeixinUtil.getAccessTicket(accessToken.getToken());
Map<String, String> ret = WeixinUtil.sign(accessTicket.getTicket(), url);
for (Map.Entry entry : ret.entrySet()) {
String key = entry.getKey().toString();
String value = entry.getValue().toString();
if("timestamp".equals(key)){
jsConfig.setTimestamp(value);
} else if("nonceStr".equals(key)){
jsConfig.setNonceStr(value);
} else if("jsapi_ticket".equals(key)){
jsConfig.setJsapi_ticket(value);
} else if("signature".equals(key)){
jsConfig.setSignature(value);
} else if("url".equals(key)){
jsConfig.setUrl(value);
}
}
}
String result = new Gson().toJson(jsConfig);
log.info("获取js配置信息结果===>"+result);
out().print(result);
}
}
6:MyX509TrustManager.java
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;
}
}