packagecom.ray.util;importjava.io.BufferedReader;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.OutputStream;importjava.io.UnsupportedEncodingException;importjava.net.ConnectException;importjava.net.HttpURLConnection;importjava.net.URL;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.Formatter;importjava.util.HashMap;importjava.util.Map;importjava.util.UUID;importjavax.net.ssl.HttpsURLConnection;importjavax.net.ssl.SSLContext;importjavax.net.ssl.SSLSocketFactory;importjavax.net.ssl.TrustManager;importjavax.servlet.http.HttpServletRequest;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importcom.ray.pojo.AccessToken;importnet.sf.json.JSONException;importnet.sf.json.JSONObject;public classWeiXinUtil {private static Logger log = LoggerFactory.getLogger(WeiXinUtil.class);//微信的请求url//获取access_token的接口地址(GET) 限200(次/天)
public final static String access_token_url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpId}&corpsecret={corpsecret}";/*** 1.发起https请求并获取结果
*
*@paramrequestUrl 请求地址
*@paramrequestMethod 请求方式(GET、POST)
*@paramoutputStr 提交的数据
*@returnJSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)*/
public staticJSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject= null;
StringBuffer buffer= newStringBuffer();try{//创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { newMyX509TrustManager() };
SSLContext sslContext= SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, newjava.security.SecureRandom());//从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf =sslContext.getSocketFactory();
URL url= newURL(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= newBufferedReader(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) {
log.error("Weixin server connection timed out.");
}catch(Exception e) {
log.error("https request error:{}", e);
}returnjsonObject;
}/*** @desc :微信上传素材的请求方法
*
*@paramrequestUrl 微信上传临时素材的接口url
*@paramfile 要上传的文件
*@returnString 上传成功后,微信服务器返回的消息*/
public staticString httpRequest(String requestUrl, File file) {
StringBuffer buffer= newStringBuffer();try{//1.建立连接
URL url = newURL(requestUrl);
HttpURLConnection httpUrlConn= (HttpURLConnection) url.openConnection(); //打开链接//1.1输入输出设置
httpUrlConn.setDoInput(true);
httpUrlConn.setDoOutput(true);
httpUrlConn.setUseCaches(false); //post方式不能使用缓存//1.2设置请求头信息
httpUrlConn.setRequestProperty("Connection", "Keep-Alive");
httpUrlConn.setRequestProperty("Charset", "UTF-8");//1.3设置边界
String BOUNDARY = "----------" +System.currentTimeMillis();
httpUrlConn.setRequestProperty("Content-Type","multipart/form-data; boundary="+BOUNDARY);//请求正文信息//第一部分://2.将文件头输出到微信服务器
StringBuilder sb = newStringBuilder();
sb.append("--"); //必须多两道线
sb.append(BOUNDARY);
sb.append("\r\n");
sb.append("Content-Disposition: form-data;name=\"media\";filelength=\"" +file.length()+ "\";filename=\""+ file.getName() + "\"\r\n");
sb.append("Content-Type:application/octet-stream\r\n\r\n");byte[] head = sb.toString().getBytes("utf-8");//获得输出流
OutputStream outputStream = newDataOutputStream(httpUrlConn.getOutputStream());//将表头写入输出流中:输出表头
outputStream.write(head);//3.将文件正文部分输出到微信服务器//把文件以流文件的方式 写入到微信服务器中
DataInputStream in = new DataInputStream(newFileInputStream(file));int bytes = 0;byte[] bufferOut = new byte[1024];while ((bytes = in.read(bufferOut)) != -1) {
outputStream.write(bufferOut,0, bytes);
}
in.close();//4.将结尾部分输出到微信服务器
byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");//定义最后数据分隔线
outputStream.write(foot);
outputStream.flush();
outputStream.close();//5.将微信服务器返回的输入流转换成字符串
InputStream inputStream =httpUrlConn.getInputStream();
InputStreamReader inputStreamReader= new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader= newBufferedReader(inputStreamReader);
String str= null;while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();//释放资源
inputStream.close();
inputStream= null;
httpUrlConn.disconnect();
}catch(IOException e) {
System.out.println("发送POST请求出现异常!" +e);
e.printStackTrace();
}returnbuffer.toString();
}/*** 2.发起http请求获取返回结果
*
*@paramrequestUrl 请求地址
*@return
*/
public staticString httpRequest(String requestUrl) {
StringBuffer buffer= newStringBuffer();try{
URL url= newURL(requestUrl);
HttpURLConnection httpUrlConn=(HttpURLConnection) url.openConnection();
httpUrlConn.setDoOutput(false);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
httpUrlConn.setRequestMethod("GET");
httpUrlConn.connect();//将返回的输入流转换成字符串
InputStream inputStream =httpUrlConn.getInputStream();
InputStreamReader inputStreamReader= new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader= newBufferedReader(inputStreamReader);
String str= null;while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();//释放资源
inputStream.close();
inputStream= null;
httpUrlConn.disconnect();
}catch(Exception e) {
}returnbuffer.toString();
}/*** 3.获取access_token
*
*@paramappid 凭证
*@paramappsecret 密钥
*@return
*/
public staticAccessToken getAccessToken(String appid, String appsecret) {
AccessToken accessToken= null;
String requestUrl= access_token_url.replace("{corpId}", appid).replace("{corpsecret}", appsecret);
JSONObject jsonObject= httpRequest(requestUrl, "GET", null);//如果请求成功
if (null !=jsonObject) {try{
accessToken= newAccessToken();
accessToken.setToken(jsonObject.getString("access_token"));
accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
}catch(JSONException e) {
accessToken= null;//获取token失败
log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
}
}returnaccessToken;
}/*** 3.获取微信的JSSDK配置信息
* 方法名:getWxConfig
* 详述:获取微信的配置信息
* 开发人员:souvc
* 创建时间:2016-1-5
*@paramrequest
*@return说明返回值含义
*@throws说明发生此异常的条件*/
public static MapgetWxConfig(HttpServletRequest request) {
Map ret = new HashMap();
String appId= "wxa0064ea657f80062"; //必填,公众号的唯一标识
String secret = "fcc960840df869ad1a46af7993784917";
String requestUrl=request.getRequestURL().toString();
String access_token= "";
String jsapi_ticket= "";
String timestamp= Long.toString(System.currentTimeMillis() / 1000); //必填,生成签名的时间戳
String nonceStr = UUID.randomUUID().toString(); //必填,生成签名的随机串
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appId + "&secret=" +secret;//使用http请求获取access_token
JSONObject json = WeiXinUtil.httpRequest(url, "GET", null);
System.out.println(" 获取access_token "+json);if (json != null) {//要注意,access_token需要缓存
access_token = json.getString("access_token");//根据access_token获取jsapi_ticket
url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token + "&type=jsapi";
json= WeiXinUtil.httpRequest(url, "GET", null);
System.out.println("jsapi_ticket "+json);if (json != null) {
jsapi_ticket= json.getString("ticket");
}
}
String signature= "";//注意这里参数名必须全部小写,且必须有序
String sign = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr+ "×tamp=" + timestamp + "&url=" +requestUrl;try{
MessageDigest crypt= MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(sign.getBytes("UTF-8"));
signature=byteToHex(crypt.digest());
}catch(NoSuchAlgorithmException e) {
e.printStackTrace();
}catch(UnsupportedEncodingException e) {
e.printStackTrace();
}
ret.put("appId", appId);
ret.put("timestamp", timestamp);
ret.put("nonceStr", nonceStr);
ret.put("signature", signature);returnret;
}/*** 方法名:byteToHex
* 详述:字符串加密辅助方法
* 开发人员:souvc
* 创建时间:2016-1-5
*@paramhash
*@return说明返回值含义
*@throws说明发生此异常的条件*/
private static String byteToHex(final byte[] hash) {
Formatter formatter= newFormatter();for (byteb : hash) {
formatter.format("%02x", b);
}
String result=formatter.toString();
formatter.close();returnresult;
}
}