JAVA微信公众号网页开发 —— 用户授权获取openid
官方文档: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;
}
}
JAVA微信公众号网页开发 —— 用户授权获取openid的更多相关文章
- JAVA微信公众号网页开发——获取公众号关注的所有用户(微信公众号粉丝)
package com.weixin.sendmessage; import org.apache.commons.lang.StringUtils; import org.apache.http.H ...
- JAVA微信公众号网页开发——将接收的消息转发到微信自带的客服系统
如果公众号处于开发模式,普通微信用户向公众号发消息时,微信服务器会先将消息POST到开发者填写的url上,无法直接推送给微信自带的客服功能.如果需要把用户推送的普通消息推送到客服功能中,就需要进行代码 ...
- JAVA微信公众号网页开发 —— 接收微信服务器发送的消息
WeixinMessage.java package com.test; import java.io.Serializable; /** * This is an object that conta ...
- JAVA微信公众号网页开发——通过接收人的openid发送模板消息
TemplateData.java 1 package com.weixin.weixin.template; 2 3 public class TemplateData { 4 private St ...
- JAVA微信公众号网页开发——生成自定义微信菜单(携带参数)
官网接口地址:https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Creating_Custom-Defined_Menu.ht ...
- JAVA微信公众号网页开发——将文章群发到微信公众号中(文章使用富文本,包含图片)
SendTextToAllUserAct.java package com.weixin.sendmessage; import org.apache.commons.lang.StringUtils ...
- C#开发微信公众号——网页开发之微信网页授权
首先咱们先看下公众号的文档里面的介绍 上述图片的文字描述就是讲述了网页授权有什么用,就是为了获取微信用户的基本信息:授权回调域名的规范,说到域名回调的事情就不得不提一下设置网页授权域名 最好将这三个域 ...
- 微信公众号网页开发-jssdk config配置参数生成(Java版)
一.配置参数 参考官方文档:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&la ...
- C#微信公众号接口开发,灵活利用网页授权、带参数二维码、模板消息,提升用户体验之完成用户绑定个人微信及验证码获取
一.前言 当下微信公众号几乎已经是每个公司必备的,但是大部分微信公众账号用户体验都欠佳,特别是涉及到用户绑定等,需要用户进行复杂的操作才可以和网站绑定,或者很多公司直接不绑定,而是每次都让用户填写账号 ...
随机推荐
- layui form表单自定义sm格式
1. 新建以下sm样式,保存为layform_sm.css文件名,然后导入到layui.css的后面. .layui-input-sm,.layui-select-sm,.layui-textarea ...
- js对象与字符串的想到转换
js JSON.stringify(jsObj); 对象转字符串JSON.parse(str); 字符串转对象
- web worker 简介
web worker 简介 通常,浏览器执行某段程序的时候会阻塞直到运行结束后在恢复到正常状态,而HTML5的Web Worker就是为了解决这个问题.通过worker线程完成密集计算,避免程序的阻塞 ...
- nodejs在windows下的安装配置(使用NVM的方式)
NVM的安装 1.下载安装包,https://github.com/coreybutler/nvm-windows/releases 2.下载完成后点击nvm-setup,按步骤安装,注意路径中不能带 ...
- mvc 根据模板导出excel,直接导出文件流
1.c# /// <summary> /// 导出员工 /// </summary> /// <returns></returns> [HttpGet] ...
- mysql关联表修改语句
UPDATE tb_irms_trans_pip2optseg a,`tb_irms_trans_pip` b SET a.district=b.district WHERE a.prop_id=b. ...
- cocos2dx添加新的类后出现错误undefined reference to的解决办法
使用cocos compile -p android编译cocos2dx项目的时候出现如下错误(新建了TestScene.h,TestScene.cpp): jni/../../Classes/App ...
- SublimeText插件Pandoc导出PDF中文报错或者中文不显示解决方法
按照如下自定义配置(主要是指定latex的字体[仅限本机字体]) { "user": { // "pandoc-path":"C:\\Program ...
- 机器人学 —— 机器人感知(Location)
终于完成了Robotic SLAM 所有的内容了.说实话,课程的内容比较一般,但是作业还是挺有挑战性的.最后一章的内容是 Location. Location 是 Mapping 的逆过程.在给定ma ...
- Python学习之旅(二十三)
Python基础知识(22):进程和线程(Ⅰ) 1.多进程 (1)fork Python的os模块封装了常见的系统调用,其中就包括fork,可以在Python程序中轻松创建子进程 fork可以在Mac ...