配置好了,就可以进行开发了,首先来看一下具体的流程:
其实很多功能点,前面已经实现过,只用改一下调用地址和参数即可。
首先,调用的定义链接:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
链接中需要使用urlEncode对链接进行处理,可以在工具类中添加一个转码方法:
1 /**
2 * 对URL地址进行EnCode处理3 *@paramurl4 *@return
5 */
6 public staticString urlEnCode(String url)7 {8 String enCodedUrl = "";9
10 try
11 {12 enCodedUrl = URLEncoder.encode(url, "utf-8");13 }14 catch(UnsupportedEncodingException e)15 {16 //TODO Auto-generated catch block
17 e.printStackTrace();18 System.out.println("转码失败!");19 }20
21 returnenCodedUrl;22 }
另外将其他参数补充完整,可以得到一个访问链接。
在这里,可以结合之前学的菜单的处理,可以定义一个菜单进行专门的授权验证,这里需要改造上一节学到的点,具体如下:
1 /**
2 * 定义菜单属性3 *@return
4 */
5 privateMenu getMenu()6 {7 Menu menu = newMenu();8
9 //建3个导航菜单
10 LevelMenu tLevelMenuOne = newLevelMenu();11 tLevelMenuOne.setName("Damon");12 LevelMenu tLevelMenuTwo = newLevelMenu();13 tLevelMenuTwo.setName("Panou");14 LevelMenu tLevelMenuThree = newLevelMenu();15 tLevelMenuThree.setName("Papaw");16
17 //第一个导航菜单的子菜单
18 SubMenuButton tSubMenuButton_oneone = newSubMenuButton();19 tSubMenuButton_oneone.setType(SysCon.WECHAT_MENU_TYPE_VIEW);20 tSubMenuButton_oneone.setName("网页授权");21 tSubMenuButton_oneone.setKey("11");22 tSubMenuButton_oneone.setUrl(getAuthorUrl());23
24 SubMenuButton tSubMenuButton_onetwo = newSubMenuButton();25 tSubMenuButton_onetwo.setType(SysCon.WECHAT_MENU_TYPE_CLICK);26 tSubMenuButton_onetwo.setName("swimming");27 tSubMenuButton_onetwo.setKey("12");28
29 //加入导航菜单
30 tLevelMenuOne.setSub_button(newSubMenuButton[]31 { tSubMenuButton_oneone, tSubMenuButton_onetwo });32
33 //第二 个导航菜单的子菜单
34 SubMenuButton tSubMenuButton_twoone = newSubMenuButton();35 tSubMenuButton_twoone.setType(SysCon.WECHAT_MENU_TYPE_CLICK);36 tSubMenuButton_twoone.setName("watching TV");37 tSubMenuButton_twoone.setKey("21");38
39 SubMenuButton tSubMenuButton_twotwo = newSubMenuButton();40 tSubMenuButton_twotwo.setType(SysCon.WECHAT_MENU_TYPE_CLICK);41 tSubMenuButton_twotwo.setName("play games");42 tSubMenuButton_twotwo.setKey("22");43
44 SubMenuButton tSubMenuButton_twothree = newSubMenuButton();45 tSubMenuButton_twothree.setType(SysCon.WECHAT_MENU_TYPE_CLICK);46 tSubMenuButton_twothree.setName("shopping");47 tSubMenuButton_twothree.setKey("23");48
49 //加入导航菜单
50 tLevelMenuTwo.setSub_button(newSubMenuButton[]51 { tSubMenuButton_twoone, tSubMenuButton_twotwo, tSubMenuButton_twothree });52
53 //第三个导航菜单的子菜单
54 SubMenuButton tSubMenuButton_threeone = newSubMenuButton();55 tSubMenuButton_threeone.setType(SysCon.WECHAT_MENU_TYPE_CLICK);56 tSubMenuButton_threeone.setName("cring");57 tSubMenuButton_threeone.setKey("31");58
59 SubMenuButton tSubMenuButton_threetwo = newSubMenuButton();60 tSubMenuButton_threetwo.setType(SysCon.WECHAT_MENU_TYPE_CLICK);61 tSubMenuButton_threetwo.setName("laughing");62 tSubMenuButton_threetwo.setKey("32");63
64 //加入导航菜单
65 tLevelMenuThree.setSub_button(newSubMenuButton[]66 { tSubMenuButton_threeone, tSubMenuButton_threetwo });67
68 menu.setButton(newMenuButton[]69 { tLevelMenuOne, tLevelMenuTwo, tLevelMenuThree });70
71 returnmenu;72
73 }74
75 /**
76 * 获取微信网页授权页面链接77 *@return
78 */
79 privateString getAuthorUrl()80 {81 String uri = "http://damonhouse.iok.la/Servlet/WeChatAuthorService";82
83 uri =WeChatUtil.urlEnCode(uri);84
85 String authorUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";86
87 authorUrl = authorUrl.replace("APPID", "appid").replace("REDIRECT_URI", uri).replace("SCOPE", "snsapi_userinfo");88
89 returnauthorUrl;90 }
先看一下具体效果:
点击会弹出一个授权的页面(由于我已经授权过,所以这里会自动登录)
这个时候后台还没有对应的处理,我们需要进行返回页面的处理,这里定义对应的service类,在doGet方法中进行处理:
1 /**
2 * 微信授权接口类3 *@authorDamon4 */
5 public class WeChatAuthorService extendsHttpServlet6 {7
8 @Override9 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throwsServletException, IOException10 {11 //TODO Auto-generated method stub
12 System.out.println("授权成功,进行返回处理!");13 req.setCharacterEncoding("utf-8");14 resp.setCharacterEncoding("utf-8");15
16 String code = req.getParameter("code");17
18 String state = req.getParameter("state");19
20 System.out.println("code :" + code + " and stat :" +state);21
22 //业务处理,获取授权用户信息
23 WeChatAuthorBL tWeChatAuthorBL = newWeChatAuthorBL();24 AuthorUserInfo tAuthorUserInfo =tWeChatAuthorBL.getAuthorData(code, state);25
26 req.setAttribute("nickname", tAuthorUserInfo.getNickname());27 //获取信息成功,回写成功页面
28 req.getRequestDispatcher("../wechat/authorsucc.jsp").forward(req, resp);29
30 }31
32 @Override33 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throwsServletException, IOException34 {35 //TODO Auto-generated method stub
36 super.doPost(req, resp);37 }38
39
40 }
可以从授权中获取到 code 和state(可自定义用与此处校验), 然后就是通过code来进行获取授权的用户信息:
从前面分析可知,需要先获取授权的acces_token,然后才能获取到授权的用户信息,那么结合前面2节内容,先定义2个实体类:
1、用户授权Token类
1 /**
2 * 用户授权Token3 *@authorDamon4 */
5 public classAuthorToken6 {7 //网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
8 private String access_token = "";9
10 //access_token接口调用凭证超时时间,单位(秒)
11 private int expires_in = 0;12
13 //用户刷新access_token ="";
14 private String refresh_token = "";15
16 //用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
17 private String openid = "";18
19 //用户授权的作用域,使用逗号(,)分隔
20 private String scope = "";21
22 publicString getAccess_token()23 {24 returnaccess_token;25 }26
27 public voidsetAccess_token(String access_token)28 {29 this.access_token =access_token;30 }31
32 public intgetExpires_in()33 {34 returnexpires_in;35 }36
37 public void setExpires_in(intexpires_in)38 {39 this.expires_in =expires_in;40 }41
42 publicString getRefresh_token()43 {44 returnrefresh_token;45 }46
47 public voidsetRefresh_token(String refresh_token)48 {49 this.refresh_token =refresh_token;50 }51
52 publicString getOpenid()53 {54 returnopenid;55 }56
57 public voidsetOpenid(String openid)58 {59 this.openid =openid;60 }61
62 publicString getScope()63 {64 returnscope;65 }66
67 public voidsetScope(String scope)68 {69 this.scope =scope;70 }71
72 }
2、授权用户信息类
1 /**
2 * 通过网页授权获取的用户信息3 *@authorDamon4 */
5 public classAuthorUserInfo6 {7 //用户的唯一标识
8 private String openid = "";9
10 //用户昵称
11 private String nickname = "";12
13 //用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
14 private String sex = "";15
16 //用户个人资料填写的省份
17 private String province = "";18
19 //普通用户个人资料填写的城市
20 private String city = "";21
22 //国家,如中国为CN
23 private String country = "";24
25 //用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
26 private String headimgurl = "";27
28 //用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)
29 private List privilege = new ArrayList();30
31 //只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
32 private String unionid = "";33
34 publicString getOpenid()35 {36 returnopenid;37 }38
39 public voidsetOpenid(String openid)40 {41 this.openid =openid;42 }43
44 publicString getNickname()45 {46 returnnickname;47 }48
49 public voidsetNickname(String nickname)50 {51 this.nickname =nickname;52 }53
54 publicString getSex()55 {56 returnsex;57 }58
59 public voidsetSex(String sex)60 {61 this.sex =sex;62 }63
64 publicString getProvince()65 {66 returnprovince;67 }68
69 public voidsetProvince(String province)70 {71 this.province =province;72 }73
74 publicString getCity()75 {76 returncity;77 }78
79 public voidsetCity(String city)80 {81 this.city =city;82 }83
84 publicString getCountry()85 {86 returncountry;87 }88
89 public voidsetCountry(String country)90 {91 this.country =country;92 }93
94 publicString getHeadimgurl()95 {96 returnheadimgurl;97 }98
99 public voidsetHeadimgurl(String headimgurl)100 {101 this.headimgurl =headimgurl;102 }103
104 public ListgetPrivilege()105 {106 returnprivilege;107 }108
109 public void setPrivilege(Listprivilege)110 {111 this.privilege =privilege;112 }113
114 publicString getUnionid()115 {116 returnunionid;117 }118
119 public voidsetUnionid(String unionid)120 {121 this.unionid =unionid;122 }123
124 }
下一步,就是通过调用接口来实现我们的功能了~
1 /**
2 * 获取授权用户3 *@paramcode4 *@paramstate5 *@return
6 */
7 publicAuthorUserInfo getAuthorData(String code, String state)8 {9
10 //1、通过code获取授权的authortoken
11 AuthorToken tAuthorToken = getAuthorToken("appid", "appsecret", code);12
13 //2、通过获取的 access_token和 openid 获取用户信息
14 AuthorUserInfo tAuthorUserInfo =getAuthorUserInfo(tAuthorToken.getAccess_token(), tAuthorToken.getOpenid());15
16 returntAuthorUserInfo;17 }18
19
20 /**
21 * 获取授权的access_token22 *@paramappid23 *@paramappsceret24 *@paramcode25 *@return
26 */
27 privateAuthorToken getAuthorToken(String appid, String appsceret, String code)28 {29
30 String path = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code ";31
32 path = path.replace("APPID", appid).replace("SECRET", appsceret).replace("CODE", code);33
34 AuthorToken tAuthorToken = newAuthorToken();35
36 try
37 {38 String strResp = WeChatUtil.doHttpsGet(path, "");39
40 System.out.println(strResp);41
42 //解析获取的token信息
43 Map tMap =WeChatUtil.jsonToMap(strResp);44
45 System.out.println(tMap.toString());46
47 //封装 authortoken
48
49 tAuthorToken.setAccess_token((String) tMap.get("access_token"));50 tAuthorToken.setExpires_in(Integer.parseInt((String) tMap.get("expires_in")));51 tAuthorToken.setOpenid((String) tMap.get("openid"));52 tAuthorToken.setScope((String) tMap.get("scope"));53 tAuthorToken.setRefresh_token((String) tMap.get("refresh_token"));54
55 }56 catch(HttpException e)57 {58 //TODO Auto-generated catch block
59 e.printStackTrace();60 }61 catch(IOException e)62 {63 //TODO Auto-generated catch block
64 e.printStackTrace();65 }66
67 returntAuthorToken;68 }69
70
71 /**
72 * 通过授权的access_token及用户的openid来拉取用户信息73 *@paramaccess_token74 *@paramopenid75 *@return
76 */
77 privateAuthorUserInfo getAuthorUserInfo(String access_token, String openid)78 {79 String path = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";80
81 path = path.replace("ACCESS_TOKEN", access_token).replace("OPENID", openid);82
83 AuthorUserInfo tAuthorUserInfo = newAuthorUserInfo();84
85 try
86 {87 String strResp = WeChatUtil.doHttpsGet(path, "");88
89 System.out.println(strResp);90
91 //解析获取的token信息
92 Map tMap =WeChatUtil.jsonToMap(strResp);93
94 System.out.println(tMap.toString());95
96 //封装 authortoken
97 tAuthorUserInfo.setOpenid((String) tMap.get("openid"));98 tAuthorUserInfo.setNickname((String) tMap.get("nickname"));99 tAuthorUserInfo.setSex((String) tMap.get("sex"));100 tAuthorUserInfo.setCountry((String) tMap.get("country"));101 tAuthorUserInfo.setProvince((String) tMap.get("province"));102 tAuthorUserInfo.setCity((String) tMap.get("city"));103 tAuthorUserInfo.setHeadimgurl((String) tMap.get("headimgurl"));104 tAuthorUserInfo.setPrivilege((List) tMap.get("privilege"));105 tAuthorUserInfo.setUnionid((String) tMap.get("unionid"));106 }107 catch(HttpException e)108 {109 //TODO Auto-generated catch block
110 e.printStackTrace();111 }112 catch(IOException e)113 {114 //TODO Auto-generated catch block
115 e.printStackTrace();116 }117
118 returntAuthorUserInfo;119 }
这些搞定,我们就已经获取到了用户的信息了。 最后我们来给用户一个好的界面体验~
这里新增一个页面,显示获取到的用户昵称:
1
2 pageEncoding="GBK"%>
3
4
5
6
7
damon's house
8
9
10
11 Stringnickname=request.getAttribute("nickname").toString();12 %>
13
14
15
来看一下效果吧~
微信网页授权,获取用户信息就到这啦~