
官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
HttpClientUtil.java
package com.test; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; public class HttpClientUtil { private static class SingletonHolder{
private final static HttpClientUtil INSTANCE=new HttpClientUtil();
} private HttpClientUtil(){} public static HttpClientUtil getInstance(){
return SingletonHolder.INSTANCE;
} public String get(String url){
CharsetHandler handler = new CharsetHandler("UTF-8");
CloseableHttpClient client = null;
try {
HttpGet httpget = new HttpGet(new URI(url));
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
client= httpClientBuilder.build();
client = (CloseableHttpClient) wrapClient(client);
return client.execute(httpget, handler);
} catch (Exception e) {
//e.printStackTrace();
return "";
}finally {
try {
if(client!=null){
client.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} public static String post(String url, String params,String contentType)
{ //创建HttpClientBuilder
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
//HttpClient
CloseableHttpClient client = httpClientBuilder.build();
client = (CloseableHttpClient) wrapClient(client); HttpPost post = new HttpPost(url);
CloseableHttpResponse res = null;
try
{
StringEntity s = new StringEntity(params,"UTF-8");
if(StringUtils.isBlank(contentType)){
s.setContentType("application/json");
}
s.setContentType(contentType);
s.setContentEncoding("utf-8");
post.setEntity(s);
res = client.execute(post);
HttpEntity entity = res.getEntity();
return EntityUtils.toString(entity, "utf-8");
}
catch (Exception e)
{
e.printStackTrace();
} finally {
try {
res.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return "";
} public static String post(String urlStr,String xmlInfo) {
String line1 = "";
try {
URL url = new URL(urlStr);
URLConnection con = url.openConnection();
con.setDoOutput(true);
//con.setRequestProperty("Pragma:", "no-cache");
con.setRequestProperty("Cache-Control", "no-cache");
con.setRequestProperty("Content-Type", "text/xml"); OutputStreamWriter out = new OutputStreamWriter(con
.getOutputStream());
out.write(new String(xmlInfo.getBytes("utf-8")));
out.flush();
out.close();
BufferedReader br = new BufferedReader(new InputStreamReader(con
.getInputStream()));
String line = "";
for (line = br.readLine(); line != null; line = br.readLine()) {
line1+=line;
}
return new String(line1.getBytes(),"utf-8");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
} private class CharsetHandler implements ResponseHandler<String> {
private String charset; public CharsetHandler(String charset) {
this.charset = charset;
} public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
HttpEntity entity = response.getEntity();
if (entity != null) {
if (!StringUtils.isBlank(charset)) {
return EntityUtils.toString(entity, charset);
} else {
return EntityUtils.toString(entity);
}
} else {
return null;
}
}
} private static HttpClient wrapClient(HttpClient base) {
try {
SSLContext ctx = SSLContext.getInstance("TLSv1");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
} public void checkServerTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
} public X509Certificate[] 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();
return httpclient; } catch (Exception ex) {
return null;
}
} }
(注:获取到的code只能使用一次,每次请求都要重新获取一次code,因此以下方法,如果用户重新刷新了页面,就会报错,建议把使用过的code放在缓存中,每次请求接口前判断code是否已经使用,如果使用了就重新获取code去请求接口)
MessageAct.java
package com.test; import org.apache.commons.lang.StringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter; public class MessageAct { private String appid="公众号的APP_ID"; private String secret="公众号的APP_SECRET"; /**
* 微信登录
*
* @param code
* @param redirectUrl 返回用户的登录地址
* @param request
* @param response
* @param model
* @return
* @throws IOException
*/
@RequestMapping(value = "/weixinLogin")
public String weixinLogin(String code, String redirectUrl, HttpServletRequest request, HttpServletResponse response, ModelMap model) throws IOException {
String redirect_uri = "该网站服务的域名地址"+request.getRequestURI(); //该回调地址就是当前方法的URL,需外网能够访问 //-----在这里判断code是否已经存在于缓存中,如果存在,说明code已经使用过,需要重新获取code------ //获取code
if (StringUtils.isBlank(code)) {
try {
PrintWriter out = response.getWriter();
out.println("<script>window.location.href='" + getCodeUrl(redirect_uri) + "'</script>");
out.flush();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return null;
}
String[] s = getOpenId(code);
String openId = s[0];
String accessToken = s[1];
String[] userInfo = getUserInfo(openId, accessToken);//获取用户信息
System.out.println("手机登录openId=================================>" + openId);
User user = userMng.findById(openId); //查询用户是否存在,openId 作为查询条件
if (user != null) {
//用户已经存在
return redirectUrl;
} else {
//用户不存在,进行注册操作
} } /**
* 获取用户授权 得到openId,accessToken
*
* @param code
* @return
*/
public String[] getOpenId(String code) {
String tokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?grant_type=authorization_code";
tokenUrl = tokenUrl + "&appid=" + appid + "&secret=" + secret + "&code=" + code;
JSONObject json = null;
try {
json = new JSONObject(HttpClientUtil.getInstance().get(tokenUrl)); //------------在这里把使用过的code存入到缓存中-------- } catch (JSONException e2) {
e2.printStackTrace();
}
String openId = "";
String accessToken = "";
String[] s = new String[2];
if (json != null) {
try {
openId = json.getString("openid");
accessToken = json.getString("access_token");
s[0] = openId;
s[1] = accessToken;
} catch (JSONException e) {
String errcode = null;
try {
errcode = json.getString("errcode");
System.out.println("errcode================>手机登录 获取用户授权失败" + errcode);
} catch (JSONException e1) {
e1.printStackTrace();
}
}
}
return s;
} /**
* 获取用户信息 拉取用户信息(需scope为 snsapi_userinfo)
* 只有在用户将公众号绑定到微信开放平台帐号后,可以获取unionid
*
* @param
* @param
* @return
*/
public String[] getUserInfo(String openid, String accessToken) {
String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?lang=zh_CN";
userInfoUrl = userInfoUrl + "&access_token=" + accessToken + "&openid=" + openid;
JSONObject json = null;
try {
json = new JSONObject(HttpClientUtil.getInstance().get(userInfoUrl));
} catch (JSONException e2) {
e2.printStackTrace();
}
String nickname = ""; //用户昵称
String sex = ""; //用户的性别
String province = ""; //用户个人资料填写的省份
String city = ""; //普通用户个人资料填写的城市
String country = ""; //国家,如中国为CN
String headimgurl = ""; //用户头像,
String unionid = ""; //
String[] s = new String[6];
if (json != null) {
try {
nickname = json.getString("nickname");
sex = json.getString("sex");
province = json.getString("province");
city = json.getString("city");
country = json.getString("country");
headimgurl = json.getString("headimgurl");
s[0] = nickname;
s[1] = sex;
s[2] = province;
s[3] = city;
s[4] = country;
s[5] = headimgurl;
} catch (JSONException e) {
String errcode = null;
try {
errcode = json.getString("errcode");
System.out.println("errcode================>获取用户信息失败" + errcode);
} catch (JSONException e1) {
e1.printStackTrace();
}
}
}
return s;
} /**
* 获取code请求地址
*
* @param redirect_uri 回调地址 这个回调地址需要在微信公众号后台也进行配置 不然会显示"redirect_uri域名还是与后台配置不一致"
* @param
* @return
*/
public String getCodeUrl(String redirect_uri) {
redirect_uri=URLEncoder.encode(redirect_uri); //使用 urlEncode 对链接进行处理
String codeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize";
codeUrl = codeUrl + "?appid=" + appid + "&redirect_uri=" + redirect_uri
+ "&response_type=code&scope=snsapi_userinfo&state=jetcms#wechat_redirect"; return codeUrl;
}
}