一、准备
1、一个微信公众号,也可以申请一个测试号。
测试号申请网址:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
2、云主机,将项目部署在云服务上。
3、设置回调页面。(域名)
微信公众平台开发文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432
二、获取过程
1、用户同意授权,获取code
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
解析:appid:公众号的唯一标识(将APPID替换成自己的APPID)
redirect_uri:回页面(将REDIRECT_URI替换成回调页面,我是用的是Controller的路径:
http://域名/项目名/getcode 需要编码,编码方法详见utf-8编码文章)
response_type:返回值类型,值为是code
cope:应用授权作用域,snsapi_base 不弹出授权页面,可以直接跳转,只能获取用户openid,
snsapi_userinfo ,弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只
要用户授权,也能获取其信息 。(我们使用snsapi_userinfo)
替换完成后:访问网址,获取到code值,这个值在5分钟之后失效
2、通过code获得页面授权access_token
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
解析:
appid:公众号的唯一标识(将APPID替换成自己的appid)
secret:替换公众号的appsecret(将SECRET替换成公告中号的appsecret)
code:刚刚获取的code值
替换完成后:访问网址,返回:
{ "access_token":"ACCESS_TOKEN","expires_in":7200,"refresh_token":"REFRESH_TOKEN","openid":"OPENID",
"scope":"SCOPE" }
3、获取用户信息
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
解析:
access_token:替换成access_token的值
openid:替换成openid的值
替换完成后:访问网址,返回用户信息(json数据包)
{ "openid":" OPENID",
" nickname": NICKNAME,
"sex":"1",
"province":"PROVINCE"
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://thirdwx.qlogo.cn/mmopen/
g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
"privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
可以看到我们获取到的用户的信息。
三、https工具类
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
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 net.sf.json.JSONObject;
public class Util {
/**
* 发送https请求
*
* @param requestUrl 请求地址,获取access_token的网址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpsRequest(String requestUrl, String requestMethod) {
JSONObject jsonObject = null;
try {
// 1.创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 2.从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
//3.创建URL对象,打开连接
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 4.设置请求方式(GET/POST)
conn.setRequestMethod(requestMethod);
// 5.从输入流读取返回内容,读的的返回的内容
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);
}
//打印这个字符串
System.out.println("返回信息:"+buffer);
// 释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
//转换成json对象
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
System.out.println(ce.toString());
//log.error("连接超时:{}", ce);
} catch (Exception e) {
//log.error("https请求异常:{}", e);
System.out.println(e.toString());
}
return jsonObject;
}
//写测试。
public static void main(String[] args) {
//根据code得到accesstoken, openid
JSONObject o = httpsRequest("https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx0156cb18976c3f90&secret=1bcb2d21ce527777ca4593bf452f48dc&code=071ZFuGj05fLQn1GszGj00fuGj0ZFuGa&grant_type=authorization_code","GET");
String access_token = o.getString("access_token");
String openid = o.getString("openid");
//根据accesstoken, openid得到用户信息
String url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
url = url.replace("ACCESS_TOKEN", access_token);
url = url.replace("OPENID", openid);
System.out.println(url);
JSONObject o2 = httpsRequest(url,"GET");
System.out.println("昵称是:"+o2.getString("nickname"));
System.out.println("姓名是:"+o2.getString("sex"));
System.out.println("头像是:"+o2.getString("headimgurl"));
}
}
四、使用
@Controller
public class WeiXinController{
@RequestMapping("/getcode")
public String getCode(HttpServletRequest request)
{
//1.得到微信返给的code
String code = request.getParameter("code");
//2.根据code得到access_token和openid
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
url = url.replace("APPID", "wxbf9210646fd3bb89");
url = url.replace("SECRET", "9c7874ad52b1f5ba54c5985e52ef1b82");
url = url.replace("CODE", code);
JSONObject obj = Util.httpsRequest(url, "GET");
//3.根据access_token和openid得到用户信息
String url2 = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
url2 = url2.replace("ACCESS_TOKEN", obj.getString("access_token"));
url2 = url2.replace("OPENID", obj.getString("openid"));
JSONObject obj2 =Util.httpsRequest(url2, "GET");
//4.把当前用户信息放在session中
request.getSession().setAttribute("userinfo", obj2);
//5. 页面跳转到index.html
return "redirect:index.html";
}
}
//发送https请求的MyX509TrustManager类
public class MyX509TrustManager implements X509TrustManager {
// 检查客户端证书
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
// 检查服务器端证书
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
// 返回受信任的X509证书数组
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
访问时,就要先访问获取code的替换信息后的网址。
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect