配置好了,就能夠進行開發了,首先來看一下具體的流程:html
其實不少功能點,前面已經實現過,只用改一下調用地址和參數便可。java
首先,調用的定義連接:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirectjson
連接中須要使用urlEncode對連接進行處理,能夠在工具類中添加一個轉碼方法:api
1 /** 2 * 對URL地址進行EnCode處理 3 * @param url 4 * @return 5 */ 6 public static String 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 return enCodedUrl; 22 }
另外將其餘參數補充完整,能夠獲得一個訪問連接。 數組
在這裏,能夠結合以前學的菜單的處理,能夠定義一個菜單進行專門的受權驗證,這裏須要改造上一節學到的點,具體以下:微信
1 /** 2 * 定義菜單屬性 3 * @return 4 */ 5 private Menu getMenu() 6 { 7 Menu menu = new Menu(); 8 9 // 建3個導航菜單 10 LevelMenu tLevelMenuOne = new LevelMenu(); 11 tLevelMenuOne.setName("Damon"); 12 LevelMenu tLevelMenuTwo = new LevelMenu(); 13 tLevelMenuTwo.setName("Panou"); 14 LevelMenu tLevelMenuThree = new LevelMenu(); 15 tLevelMenuThree.setName("Papaw"); 16 17 // 第一個導航菜單的子菜單 18 SubMenuButton tSubMenuButton_oneone = new SubMenuButton(); 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 = new SubMenuButton(); 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(new SubMenuButton[] 31 { tSubMenuButton_oneone, tSubMenuButton_onetwo }); 32 33 // 第二 個導航菜單的子菜單 34 SubMenuButton tSubMenuButton_twoone = new SubMenuButton(); 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 = new SubMenuButton(); 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 = new SubMenuButton(); 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(new SubMenuButton[] 51 { tSubMenuButton_twoone, tSubMenuButton_twotwo, tSubMenuButton_twothree }); 52 53 // 第三個導航菜單的子菜單 54 SubMenuButton tSubMenuButton_threeone = new SubMenuButton(); 55 tSubMenuButton_threeone.setType(SysCon.WECHAT_MENU_TYPE_CLICK); 56 tSubMenuButton_threeone.setName("cring"); 57 tSubMenuButton_threeone.setKey("31"); 58 59 SubMenuButton tSubMenuButton_threetwo = new SubMenuButton(); 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(new SubMenuButton[] 66 { tSubMenuButton_threeone, tSubMenuButton_threetwo }); 67 68 menu.setButton(new MenuButton[] 69 { tLevelMenuOne, tLevelMenuTwo, tLevelMenuThree }); 70 71 return menu; 72 73 } 74 75 /** 76 * 獲取微信網頁受權頁面連接 77 * @return 78 */ 79 private String 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 return authorUrl; 90 }
先看一下具體效果:app
點擊會彈出一個受權的頁面(因爲我已經受權過,因此這裏會自動登陸)jsp
這個時候後臺尚未對應的處理,咱們須要進行返回頁面的處理,這裏定義對應的service類,在doGet方法中進行處理:ide
1 /** 2 * 微信受權接口類 3 * @author Damon 4 */ 5 public class WeChatAuthorService extends HttpServlet 6 { 7 8 @Override 9 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 10 { 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 = new WeChatAuthorBL(); 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 @Override 33 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 34 { 35 // TODO Auto-generated method stub 36 super.doPost(req, resp); 37 } 38 39 40 }
能夠從受權中獲取到 code 和state(可自定義用與此處校驗), 而後就是經過code來進行獲取受權的用戶信息:工具
從前面分析可知,須要先獲取受權的acces_token,而後才能獲取到受權的用戶信息,那麼結合前面2節內容,先定義2個實體類:
一、用戶受權Token類
1 /** 2 * 用戶受權Token 3 * @author Damon 4 */ 5 public class AuthorToken 6 { 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 public String getAccess_token() 23 { 24 return access_token; 25 } 26 27 public void setAccess_token(String access_token) 28 { 29 this.access_token = access_token; 30 } 31 32 public int getExpires_in() 33 { 34 return expires_in; 35 } 36 37 public void setExpires_in(int expires_in) 38 { 39 this.expires_in = expires_in; 40 } 41 42 public String getRefresh_token() 43 { 44 return refresh_token; 45 } 46 47 public void setRefresh_token(String refresh_token) 48 { 49 this.refresh_token = refresh_token; 50 } 51 52 public String getOpenid() 53 { 54 return openid; 55 } 56 57 public void setOpenid(String openid) 58 { 59 this.openid = openid; 60 } 61 62 public String getScope() 63 { 64 return scope; 65 } 66 67 public void setScope(String scope) 68 { 69 this.scope = scope; 70 } 71 72 }
二、受權用戶信息類
1 /** 2 * 經過網頁受權獲取的用戶信息 3 * @author Damon 4 */ 5 public class AuthorUserInfo 6 { 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、4六、6四、9六、132數值可選,0表明640*640正方形頭像),用戶沒有頭像時該項爲空。若用戶更換頭像,原有頭像URL將失效。 26 private String headimgurl = ""; 27 28 // 用戶特權信息,json 數組,如微信沃卡用戶爲(chinaunicom) 29 private List<String> privilege = new ArrayList<String>(); 30 31 // 只有在用戶將公衆號綁定到微信開放平臺賬號後,纔會出現該字段。 32 private String unionid = ""; 33 34 public String getOpenid() 35 { 36 return openid; 37 } 38 39 public void setOpenid(String openid) 40 { 41 this.openid = openid; 42 } 43 44 public String getNickname() 45 { 46 return nickname; 47 } 48 49 public void setNickname(String nickname) 50 { 51 this.nickname = nickname; 52 } 53 54 public String getSex() 55 { 56 return sex; 57 } 58 59 public void setSex(String sex) 60 { 61 this.sex = sex; 62 } 63 64 public String getProvince() 65 { 66 return province; 67 } 68 69 public void setProvince(String province) 70 { 71 this.province = province; 72 } 73 74 public String getCity() 75 { 76 return city; 77 } 78 79 public void setCity(String city) 80 { 81 this.city = city; 82 } 83 84 public String getCountry() 85 { 86 return country; 87 } 88 89 public void setCountry(String country) 90 { 91 this.country = country; 92 } 93 94 public String getHeadimgurl() 95 { 96 return headimgurl; 97 } 98 99 public void setHeadimgurl(String headimgurl) 100 { 101 this.headimgurl = headimgurl; 102 } 103 104 public List<String> getPrivilege() 105 { 106 return privilege; 107 } 108 109 public void setPrivilege(List<String> privilege) 110 { 111 this.privilege = privilege; 112 } 113 114 public String getUnionid() 115 { 116 return unionid; 117 } 118 119 public void setUnionid(String unionid) 120 { 121 this.unionid = unionid; 122 } 123 124 }
下一步,就是經過調用接口來實現咱們的功能了~
1 /** 2 * 獲取受權用戶 3 * @param code 4 * @param state 5 * @return 6 */ 7 public AuthorUserInfo getAuthorData(String code, String state) 8 { 9 10 // 一、經過code獲取受權的authortoken 11 AuthorToken tAuthorToken = getAuthorToken("appid", "appsecret", code); 12 13 // 二、經過獲取的 access_token和 openid 獲取用戶信息 14 AuthorUserInfo tAuthorUserInfo = getAuthorUserInfo(tAuthorToken.getAccess_token(), tAuthorToken.getOpenid()); 15 16 return tAuthorUserInfo; 17 } 18 19 20 /** 21 * 獲取受權的access_token 22 * @param appid 23 * @param appsceret 24 * @param code 25 * @return 26 */ 27 private AuthorToken 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 = new AuthorToken(); 35 36 try 37 { 38 String strResp = WeChatUtil.doHttpsGet(path, ""); 39 40 System.out.println(strResp); 41 42 // 解析獲取的token信息 43 Map<String, Object> 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 return tAuthorToken; 68 } 69 70 71 /** 72 * 經過受權的access_token及用戶的openid來拉取用戶信息 73 * @param access_token 74 * @param openid 75 * @return 76 */ 77 private AuthorUserInfo 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 = new AuthorUserInfo(); 84 85 try 86 { 87 String strResp = WeChatUtil.doHttpsGet(path, ""); 88 89 System.out.println(strResp); 90 91 // 解析獲取的token信息 92 Map<String, Object> 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<String>) 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 return tAuthorUserInfo; 119 }
這些搞定,咱們就已經獲取到了用戶的信息了。 最後咱們來給用戶一個好的界面體驗~
這裏新增一個頁面,顯示獲取到的用戶暱稱:
1 <%@ page language="java" contentType="text/html; charset=GBK" 2 pageEncoding="GBK"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 7 <title>damon's house</title> 8 </head> 9 <body> 10 <% 11 String nickname=request.getAttribute("nickname").toString(); 12 %> 13 <table><tr><%=nickname %> 您好,感謝受權Damon的奇趣小屋!</tr></table> 14 </body> 15 </html>
來看一下效果吧~
微信網頁受權,獲取用戶信息就到這啦~