參考摘抄: html
阿里雲部署Java網站和微信開發調試心得技巧(上):https://www.imooc.com/article/20583java
阿里雲部署Java網站和微信開發調試心得技巧(下):https://www.imooc.com/article/20584mysql
下載地址爲:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html。選擇的是jdk-8u144-linux-x64.rpm。linux
下載完成後執行:rpm -ivh jdk-8u144-linux-x64.rpmgit
下載地址爲http://tomcat.apache.org/download-80.cgi#8.0.46選擇的是apache-tomcat-8.0.46.tar.gzweb
解壓:tar -zxvf apache-tomcat-8.5.41.tar.gz redis
啓動tomcat:./apache-tomcat-8.5.41/bin/startup.shspring
修改Tomcat默認鏈接端口(8080):apache-tomcat-8.5.41/conf/server.xmlsql
修改完成後重啓Tomcat:(注意查看端口是否開啓或被佔用)shell
關閉Tomcat服務:./apache-tomcat-8.5.41/bin/shutdown.sh
啓動Tomcat服務:./apache-tomcat-8.5.41/bin/startup.sh
查看Tomcat日誌是否啓動成功
下載的地址爲https://dev.mysql.com/downloads/repo/yum/。這裏選擇mysql57-community-release-el7-11.noarch.rpm
下載地址爲https://redis.io/download這裏選擇。redis-4.0.2.tar.gz。
解壓:tar xzf redis-5.0.5.tar.gz;
設置redis以支持遠程登陸:vim redis-5.0.5/redis.conf
還須要給redis.conf添加配置以支持redis做爲守護進程一直跑在後臺daemonize yes:
注意windows下永久啓動redis:
設置服務命令:redis-server --service-install redis.windows-service.conf --loglevel verbose
經常使用redis服務命令:
卸載服務:redis-server --service-uninstall
開啓服務:redis-server --service-start
中止服務:redis-server --service-stop
安裝:cd redis-5.0.5
make
啓動服務:src/redis-server redis.conf
redis鏈接測試:
經過redis-cli鏈接到redis服務器,src/redis-cli,當輸入ping 獲得pong的迴應以後,證實redis配置已經完成
將上面的軟件都下載到本地,並上傳到服務器(若是您的系統爲MAC或LINUX,直接使用SCP命令行上傳,具體指令能夠查詢網上,若是您的系統爲WIN,推薦使用filezilla可視化上傳工具上傳),或者您也能夠直接登陸服務器,wget+ftp地址直接下載這些軟件;同時須要你們注意的是,咱們在服務器上部署了數據庫以後,須要往數據庫裏面去補充數據,咱們的線上數據訪問的是線上的數據庫而非本地的數據庫。圖片包也須要上傳到服務器並經過配置server.xml確保能讀取到這些圖片(前提是docBase配置上的路徑已經在服務器上建立)。
注:能夠利用xshell工具實現遠程鏈接(rz/sz上傳下載文件),xftp等工具實現可視化服務器與本地文件傳輸。
xshell使用
xftp工具使用
上傳成功後,沒過幾秒tomcat便會在webapps目錄下自動從項目war包中解析出項目工程目錄來
注:能夠經過查看IP加端口查看Tomcat是否啓動成功,很本機都是同樣的。
因爲域名比較貴,做爲學生黨沒敢用。之後用的時候簡單配置便可。
登陸微信公總開發平臺:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
appID:開發者ID,是公衆號開發識別碼,配合開發者密碼能夠調用微信公衆號接口,如獲取微信暱稱等
appsecret:開發者密碼,是檢驗公衆號開發者身份的密碼,具備極高的安全性。切記不要把密碼交給第三方開發者或者編寫到代碼裏
URL: 是開發者用來接收微信消息和事件的接口URL
Token:由開發者能夠任意填寫,用做生成簽名(該Token會和接口URL中包含的Token進行比對,從而驗證安全性)
注:在這裏須要驗證是否來自微信服務器
微信公衆平臺開發文檔:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319
微信請求校驗類【SigUtil】:
1 package com.swpu.o2o.util.weixin; 2 3 import java.security.MessageDigest; 4 import java.security.NoSuchAlgorithmException; 5 import java.util.Arrays; 6 7 /** 8 * 微信請求校驗工具類 9 */ 10 public class SignUtil { 11 // 與接口配置信息中的Token要一致 12 private static String token = "myo2o"; 13 14 /** 15 * 驗證簽名 16 * 17 * @param signature 18 * @param timestamp 19 * @param nonce 20 * @return 21 */ 22 public static boolean checkSignature(String signature, String timestamp, String nonce) { 23 String[] arr = new String[] { token, timestamp, nonce }; 24 // 將token、timestamp、nonce三個參數進行字典序排序 25 Arrays.sort(arr); 26 StringBuilder content = new StringBuilder(); 27 for (int i = 0; i < arr.length; i++) { 28 content.append(arr[i]); 29 } 30 MessageDigest md = null; 31 String tmpStr = null; 32 33 try { 34 md = MessageDigest.getInstance("SHA-1"); 35 // 將三個參數字符串拼接成一個字符串進行sha1加密 36 byte[] digest = md.digest(content.toString().getBytes()); 37 tmpStr = byteToStr(digest); 38 } catch (NoSuchAlgorithmException e) { 39 e.printStackTrace(); 40 } 41 42 content = null; 43 // 將sha1加密後的字符串可與signature對比,標識該請求來源於微信 44 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false; 45 } 46 47 /** 48 * 將字節數組轉換爲十六進制字符串 49 * 50 * @param byteArray 51 * @return 52 */ 53 private static String byteToStr(byte[] byteArray) { 54 String strDigest = ""; 55 for (int i = 0; i < byteArray.length; i++) { 56 strDigest += byteToHexStr(byteArray[i]); 57 } 58 return strDigest; 59 } 60 61 /** 62 * 將字節轉換爲十六進制字符串 63 * 64 * @param mByte 65 * @return 66 */ 67 private static String byteToHexStr(byte mByte) { 68 char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 69 char[] tempArr = new char[2]; 70 tempArr[0] = Digit[(mByte >>> 4) & 0X0F]; 71 tempArr[1] = Digit[mByte & 0X0F]; 72 73 String s = new String(tempArr); 74 return s; 75 } 76 }
微信請求Controller【WeChatController】:
1 package com.swpu.o2o.web.wechat; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 import org.slf4j.Logger; 10 import org.slf4j.LoggerFactory; 11 import org.springframework.stereotype.Controller; 12 import org.springframework.web.bind.annotation.RequestMapping; 13 import org.springframework.web.bind.annotation.RequestMethod; 14 15 import com.swpu.o2o.util.weixin.SignUtil; 16 17 @Controller 18 //一會在設置的URL裏面就設置上這個路由 19 @RequestMapping("wechat") 20 public class WechatController { 21 22 private static Logger log = LoggerFactory.getLogger(WechatController.class); 23 24 @RequestMapping(method = { RequestMethod.GET }) 25 public void doGet(HttpServletRequest request, HttpServletResponse response) { 26 log.debug("weixin get..."); 27 // 微信加密簽名,signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數。 28 String signature = request.getParameter("signature"); 29 // 時間戳 30 String timestamp = request.getParameter("timestamp"); 31 // 隨機數 32 String nonce = request.getParameter("nonce"); 33 // 隨機字符串 34 String echostr = request.getParameter("echostr"); 35 36 // 經過檢驗signature對請求進行校驗,若校驗成功則原樣返回echostr,表示接入成功,不然接入失敗 37 PrintWriter out = null; 38 try { 39 out = response.getWriter(); 40 if (SignUtil.checkSignature(signature, timestamp, nonce)) { 41 log.debug("weixin get success...."); 42 out.print(echostr); 43 } 44 } catch (IOException e) { 45 e.printStackTrace(); 46 } finally { 47 if (out != null) 48 out.close(); 49 } 50 } 51 }
配置成功:
域名:想調用jssdk(如想要經過微信公衆號js接口獲取地圖等工具)必須得填寫此域名,在此域名的範圍內才能調用jssdk工具,注意這裏必須是域名(IP),不是帶有http之類的URL
有不少權限可使用以下:
這裏主要介紹【網頁服務】裏面的【網頁賬號】
網頁賬號主要用來設置OAuth2.0裏面的網頁受權域名,用戶在網頁受權頁贊成受權給公衆號後,微信會將受權數據傳給一個回調頁面,回調頁面需在此域名下,以確保安全可靠。沙盒號回調地址支持域名和ip,正式公衆號回調地址只支持域名。
1 package com.swpu.o2o.web.wechat; 2 3 import java.io.IOException; 4 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletResponse; 7 8 import org.slf4j.Logger; 9 import org.slf4j.LoggerFactory; 10 import org.springframework.stereotype.Controller; 11 import org.springframework.web.bind.annotation.RequestMapping; 12 import org.springframework.web.bind.annotation.RequestMethod; 13 14 import com.swpu.o2o.dto.UserAccessToken; 15 import com.swpu.o2o.dto.WechatUser; 16 import com.swpu.o2o.util.weixin.WechatUtil; 17 18 @Controller 19 @RequestMapping("wechatlogin") 20 /** 21 * 獲取關注公衆號以後的微信用戶信息的接口,若是在微信瀏覽器裏訪問 22 * https://open.weixin.qq.com/connect/oauth2/authorize?appid=您的appId&redirect_uri=http://o2o.yitiaojieinfo.com/o2o/wechatlogin/logincheck&role_type=1&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect 23 * 則這裏將會獲取到code,以後再能夠經過code獲取到access_token 進而獲取到用戶信息 24 * 25 * 26 */ 27 public class WechatLoginController { 28 29 private static Logger log = LoggerFactory.getLogger(WechatLoginController.class); 30 31 @RequestMapping(value = "/logincheck", method = { RequestMethod.GET }) 32 public String doGet(HttpServletRequest request, HttpServletResponse response) { 33 log.debug("weixin login get..."); 34 // 獲取微信公衆號傳輸過來的code,經過code可獲取access_token,進而獲取用戶信息 35 String code = request.getParameter("code"); 36 // 這個state能夠用來傳咱們自定義的信息,方便程序調用,這裏也能夠不用 37 // String roleType = request.getParameter("state"); 38 log.debug("weixin login code:" + code); 39 WechatUser user = null; 40 String openId = null; 41 if (null != code) { 42 UserAccessToken token; 43 try { 44 // 經過code獲取access_token 45 token = WechatUtil.getUserAccessToken(code); 46 log.debug("weixin login token:" + token.toString()); 47 // 經過token獲取accessToken 48 String accessToken = token.getAccessToken(); 49 // 經過token獲取openId 50 openId = token.getOpenId(); 51 // 經過access_token和openId獲取用戶暱稱等信息 52 user = WechatUtil.getUserInfo(accessToken, openId); 53 log.debug("weixin login user:" + user.toString()); 54 request.getSession().setAttribute("openId", openId); 55 } catch (IOException e) { 56 log.error("error in getUserAccessToken or getUserInfo or findByOpenId: " + e.toString()); 57 e.printStackTrace(); 58 } 59 } 60 // ======todo begin====== 61 // 前面我們獲取到openId後,能夠經過它去數據庫判斷該微信賬號是否在咱們網站裏有對應的賬號了, 62 // 沒有的話這裏能夠自動建立上,直接實現微信與我們網站的無縫對接。 63 // ======todo end====== 64 if (user != null) { 65 // 獲取到微信驗證的信息後返回到指定的路由(須要本身設定) 66 return "frontend/index"; 67 } else { 68 return null; 69 } 70 } 71 }
1 package com.swpu.o2o.entity; 2 3 import java.util.Date; 4 5 public class PersonInfo { 6 /* 7 * 用戶信息表 8 */ 9 private Long userId; 10 private String name; 11 private String profileImg; 12 private String email; 13 private String gender; 14 private Integer enableStatus; 15 // 1.顧客 2.店家 3.超級管理員 16 private Integer userType; 17 public Long getUserId() { 18 return userId; 19 } 20 public void setUserId(Long userId) { 21 this.userId = userId; 22 } 23 public String getName() { 24 return name; 25 } 26 public void setName(String name) { 27 this.name = name; 28 } 29 public String getProfileImg() { 30 return profileImg; 31 } 32 public void setProfileImg(String profileImg) { 33 this.profileImg = profileImg; 34 } 35 public String getEmail() { 36 return email; 37 } 38 public void setEmail(String email) { 39 this.email = email; 40 } 41 public String getGender() { 42 return gender; 43 } 44 public void setGender(String gender) { 45 this.gender = gender; 46 } 47 public Integer getEnableStatus() { 48 return enableStatus; 49 } 50 public void setEnableStatus(Integer enableStatus) { 51 this.enableStatus = enableStatus; 52 } 53 public Integer getUserType() { 54 return userType; 55 } 56 public void setUserType(Integer userType) { 57 this.userType = userType; 58 } 59 public Date getCreateTime() { 60 return createTime; 61 } 62 public void setCreateTime(Date createTime) { 63 this.createTime = createTime; 64 } 65 public Date getLastEditTime() { 66 return lastEditTime; 67 } 68 public void setLastEditTime(Date lastEditTime) { 69 this.lastEditTime = lastEditTime; 70 } 71 private Date createTime; 72 private Date lastEditTime; 73 74 }
1 package com.swpu.o2o.dao; 2 3 import com.swpu.o2o.entity.PersonInfo; 4 5 public interface PersonInfoDao { 6 /** 7 * 經過用戶Id查詢用戶 8 * @param userId 9 * @return 10 */ 11 PersonInfo queryPersonInfoById(long userId); 12 /** 13 * 添加新用戶 14 * @param personInfo 15 * @return 16 */ 17 int insertPersonInfo(PersonInfo personInfo); 18 }
1 package com.swpu.o2o.entity; 2 3 import java.util.Date; 4 5 public class WechatAuth { 6 /* 7 * 微信登陸表 8 */ 9 private Long wechatAuthId; 10 private String openId; 11 private Date createTime; 12 private PersonInfo personInfo; 13 private Long userId; 14 public Long getWechatAuthId() { 15 return wechatAuthId; 16 } 17 public void setWechatAuthId(Long wechatAuthId) { 18 this.wechatAuthId = wechatAuthId; 19 } 20 public String getOpenId() { 21 return openId; 22 } 23 public void setOpenId(String openId) { 24 this.openId = openId; 25 } 26 public Date getCreateTime() { 27 return createTime; 28 } 29 public void setCreateTime(Date createTime) { 30 this.createTime = createTime; 31 } 32 public PersonInfo getPersonInfo() { 33 return personInfo; 34 } 35 public void setPersonInfo(PersonInfo personInfo) { 36 this.personInfo = personInfo; 37 } 38 public Long getUserId() { 39 return userId; 40 } 41 public void setUserId(Long userId) { 42 this.userId = userId; 43 } 44 }
1 package com.swpu.o2o.dao; 2 3 import com.swpu.o2o.entity.WechatAuth; 4 5 public interface WechatAuthDao { 6 /** 7 * 經過openId查詢對應本平臺的微信號 8 * @param openId 9 * @return 10 */ 11 WechatAuth queryWechatInfoByOpenId(String openId); 12 /** 13 * 添加對應本平臺的微信號 14 * @param wechatAuth 15 * @return 16 */ 17 int insertWechatAuth(WechatAuth wechatAuth); 18 }
用戶:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <mapper namespace="com.swpu.o2o.dao.PersonInfoDao"> 6 <select id="queryPersonInfoById" resultType="com.swpu.o2o.entity.PersonInfo" 7 parameterType="Long"> 8 SELECT 9 user_id,name,gender,email,profile_img,enable_status,user_type,create_time,last_edit_time 10 FROM tb_person_info where user_id=#{userId} 11 </select> 12 <insert id="insertPersonInfo" parameterType="com.swpu.o2o.entity.PersonInfo" 13 useGeneratedKeys="true" keyProperty="userId" keyColumn="user_id"> 14 INSERT INTO 15 tb_person_info(name,gender,email,profile_img,user_type,create_time,last_edit_time,enable_status) 16 VALUES(#{name},#{gender},#{email},#{profileImg},#{userType},#{createTime},#{lastEditTime},#{enableStatus}) 17 18 </insert> 19 </mapper>
微信信息:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <mapper namespace="com.swpu.o2o.dao.WechatAuthDao"> 6 <resultMap id="wechatAuthResultMap" type="com.swpu.o2o.entity.WechatAuth"> 7 <id property="wechatAuthId" column="wechat_auth_id" /> 8 <result property="userId" column="user_id" /> 9 <result property="openId" column="open_id" /> 10 <result property="createTime" column="create_time" /> 11 <association property="personInfo" column="user_id" 12 javaType="com.swpu.o2o.entity.PersonInfo"> 13 <id property="userId" column="user_id" /> 14 <result property="name" column="name" /> 15 <result property="gender" column="gender" /> 16 <result property="phone" column="phone" /> 17 <result property="email" column="email" /> 18 <result property="createTime" column="create_time" /> 19 <result property="lastEditTime" column="last_edit_time" /> 20 <result property="enableStatus" column="enable_status" /> 21 </association> 22 </resultMap> 23 <select id="queryWechatInfoByOpenId" parameterType="String" 24 resultMap="wechatAuthResultMap"> SELECT w.wechat_auth_id, w.user_id, w.open_id, 25 w.create_time, p.user_id, p.name, p.gender, 26 p.email, p.profile_img, p.create_time, p.last_edit_time, p.enable_status FROM 27 tb_wechat_auth w LEFT JOIN tb_person_info p ON w.user_id = p.user_id 28 WHERE w.open_id = #{openId} 29 </select> 30 <insert id="insertWechatAuth" parameterType="com.swpu.o2o.entity.WechatAuth" 31 keyColumn="wechat_auth_id" keyProperty="wechatAuthId" 32 useGeneratedKeys="true"> INSERT INTO 33 tb_wechat_auth(user_id,open_id,create_time) VALUES 34 (#{userId},#{openId},#{createTime}) 35 </insert> 36 <delete id="deleteWechatAuth"> DELETE FROM tb_wechat_auth WHERE wechat_auth_id = 37 #{wechatAuthId} 38 </delete> 39 </mapper>
1 package com.swpu.o2o.dto; 2 3 import com.fasterxml.jackson.annotation.JsonProperty; 4 5 /** 6 * 用戶受權token 7 * 8 * 9 */ 10 public class UserAccessToken { 11 12 // 獲取到的憑證 13 @JsonProperty("access_token") 14 private String accessToken; 15 // 憑證有效時間,單位:秒 16 @JsonProperty("expires_in") 17 private String expiresIn; 18 // 表示更新令牌,用來獲取下一次的訪問令牌,這裏沒太大用處 19 @JsonProperty("refresh_token") 20 private String refreshToken; 21 // 該用戶在此公衆號下的身份標識,對於此微信號具備惟一性 22 @JsonProperty("openid") 23 private String openId; 24 // 表示權限範圍,這裏可省略 25 @JsonProperty("scope") 26 private String scope; 27 28 public String getAccessToken() { 29 return accessToken; 30 } 31 32 public void setAccessToken(String accessToken) { 33 this.accessToken = accessToken; 34 } 35 36 public String getExpiresIn() { 37 return expiresIn; 38 } 39 40 public void setExpiresIn(String expiresIn) { 41 this.expiresIn = expiresIn; 42 } 43 44 public String getRefreshToken() { 45 return refreshToken; 46 } 47 48 public void setRefreshToken(String refreshToken) { 49 this.refreshToken = refreshToken; 50 } 51 52 public String getOpenId() { 53 return openId; 54 } 55 56 public void setOpenId(String openId) { 57 this.openId = openId; 58 } 59 60 public String getScope() { 61 return scope; 62 } 63 64 public void setScope(String scope) { 65 this.scope = scope; 66 } 67 68 @Override 69 public String toString() { 70 return "accessToken:" + this.getAccessToken() + ",openId:" + this.getOpenId(); 71 } 72 73 }
1 package com.swpu.o2o.dto; 2 import com.fasterxml.jackson.annotation.JsonProperty; 3 import java.io.Serializable; 4 5 /** 6 * 微信用戶實體類 7 * 8 * @author xiangze 9 * 10 */ 11 public class WechatUser implements Serializable { 12 13 /** 14 * 15 */ 16 private static final long serialVersionUID = -4684067645282292327L; 17 18 // openId,標識該公衆號下面的該用戶的惟一Id 19 @JsonProperty("openid") 20 private String openId; 21 // 用戶暱稱 22 @JsonProperty("nickname") 23 private String nickName; 24 // 性別 25 @JsonProperty("sex") 26 private int sex; 27 // 省份 28 @JsonProperty("province") 29 private String province; 30 // 城市 31 @JsonProperty("city") 32 private String city; 33 // 區 34 @JsonProperty("country") 35 private String country; 36 // 頭像圖片地址 37 @JsonProperty("headimgurl") 38 private String headimgurl; 39 // 語言 40 @JsonProperty("language") 41 private String language; 42 // 用戶權限,這裏沒什麼做用 43 @JsonProperty("privilege") 44 private String[] privilege; 45 46 public String getOpenId() { 47 return openId; 48 } 49 50 public void setOpenId(String openId) { 51 this.openId = openId; 52 } 53 54 public String getNickName() { 55 return nickName; 56 } 57 58 public void setNickName(String nickName) { 59 this.nickName = nickName; 60 } 61 62 public int getSex() { 63 return sex; 64 } 65 66 public void setSex(int sex) { 67 this.sex = sex; 68 } 69 70 public String getProvince() { 71 return province; 72 } 73 74 public void setProvince(String province) { 75 this.province = province; 76 } 77 78 public String getCity() { 79 return city; 80 } 81 82 public void setCity(String city) { 83 this.city = city; 84 } 85 86 public String getCountry() { 87 return country; 88 } 89 90 public void setCountry(String country) { 91 this.country = country; 92 } 93 94 public String getHeadimgurl() { 95 return headimgurl; 96 } 97 98 public void setHeadimgurl(String headimgurl) { 99 this.headimgurl = headimgurl; 100 } 101 102 public String getLanguage() { 103 return language; 104 } 105 106 public void setLanguage(String language) { 107 this.language = language; 108 } 109 110 public String[] getPrivilege() { 111 return privilege; 112 } 113 114 public void setPrivilege(String[] privilege) { 115 this.privilege = privilege; 116 } 117 118 @Override 119 public String toString() { 120 return "openId:" + this.getOpenId() + ",nikename:" + this.getNickName(); 121 } 122 }
1 package com.swpu.o2o.util.weixin; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.InputStreamReader; 7 import java.io.OutputStream; 8 import java.net.ConnectException; 9 import java.net.URL; 10 11 import javax.net.ssl.HttpsURLConnection; 12 import javax.net.ssl.SSLContext; 13 import javax.net.ssl.SSLSocketFactory; 14 import javax.net.ssl.TrustManager; 15 16 import org.slf4j.Logger; 17 import org.slf4j.LoggerFactory; 18 19 import com.fasterxml.jackson.core.JsonParseException; 20 import com.fasterxml.jackson.databind.JsonMappingException; 21 import com.fasterxml.jackson.databind.ObjectMapper; 22 import com.swpu.o2o.dto.UserAccessToken; 23 import com.swpu.o2o.dto.WechatUser; 24 25 /** 26 * 微信工具類 27 * 28 */ 29 public class WechatUtil { 30 31 private static Logger log = LoggerFactory.getLogger(WechatUtil.class); 32 33 /** 34 * 獲取UserAccessToken實體類 35 * 36 * @param code 37 * @return 38 * @throws IOException 39 */ 40 public static UserAccessToken getUserAccessToken(String code) throws IOException { 41 // 測試號信息裏的appId 42 String appId = "您的appId"; 43 log.debug("appId:" + appId); 44 // 測試號信息裏的appsecret 45 String appsecret = "您的appsecret"; 46 log.debug("secret:" + appsecret); 47 // 根據傳入的code,拼接出訪問微信定義好的接口的URL 48 String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appsecret 49 + "&code=" + code + "&grant_type=authorization_code"; 50 // 向相應URL發送請求獲取token json字符串 51 String tokenStr = httpsRequest(url, "GET", null); 52 log.debug("userAccessToken:" + tokenStr); 53 UserAccessToken token = new UserAccessToken(); 54 ObjectMapper objectMapper = new ObjectMapper(); 55 try { 56 // 將json字符串轉換成相應對象 57 token = objectMapper.readValue(tokenStr, UserAccessToken.class); 58 } catch (JsonParseException e) { 59 log.error("獲取用戶accessToken失敗: " + e.getMessage()); 60 e.printStackTrace(); 61 } catch (JsonMappingException e) { 62 log.error("獲取用戶accessToken失敗: " + e.getMessage()); 63 e.printStackTrace(); 64 } catch (IOException e) { 65 log.error("獲取用戶accessToken失敗: " + e.getMessage()); 66 e.printStackTrace(); 67 } 68 if (token == null) { 69 log.error("獲取用戶accessToken失敗。"); 70 return null; 71 } 72 return token; 73 } 74 75 /** 76 * 獲取WechatUser實體類 77 * 78 * @param accessToken 79 * @param openId 80 * @return 81 */ 82 public static WechatUser getUserInfo(String accessToken, String openId) { 83 // 根據傳入的accessToken以及openId拼接出訪問微信定義的端口並獲取用戶信息的URL 84 String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openId 85 + "&lang=zh_CN"; 86 // 訪問該URL獲取用戶信息json 字符串 87 String userStr = httpsRequest(url, "GET", null); 88 log.debug("user info :" + userStr); 89 WechatUser user = new WechatUser(); 90 ObjectMapper objectMapper = new ObjectMapper(); 91 try { 92 // 將json字符串轉換成相應對象 93 user = objectMapper.readValue(userStr, WechatUser.class); 94 } catch (JsonParseException e) { 95 log.error("獲取用戶信息失敗: " + e.getMessage()); 96 e.printStackTrace(); 97 } catch (JsonMappingException e) { 98 log.error("獲取用戶信息失敗: " + e.getMessage()); 99 e.printStackTrace(); 100 } catch (IOException e) { 101 log.error("獲取用戶信息失敗: " + e.getMessage()); 102 e.printStackTrace(); 103 } 104 if (user == null) { 105 log.error("獲取用戶信息失敗。"); 106 return null; 107 } 108 return user; 109 } 110 111 /** 112 * 發起https請求並獲取結果 113 * 114 * @param requestUrl 115 * 請求地址 116 * @param requestMethod 117 * 請求方式(GET、POST) 118 * @param outputStr 119 * 提交的數據 120 * @return json字符串 121 */ 122 public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) { 123 StringBuffer buffer = new StringBuffer(); 124 try { 125 // 建立SSLContext對象,並使用咱們指定的信任管理器初始化 126 TrustManager[] tm = { new MyX509TrustManager() }; 127 SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); 128 sslContext.init(null, tm, new java.security.SecureRandom()); 129 // 從上述SSLContext對象中獲得SSLSocketFactory對象 130 SSLSocketFactory ssf = sslContext.getSocketFactory(); 131 132 URL url = new URL(requestUrl); 133 HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); 134 httpUrlConn.setSSLSocketFactory(ssf); 135 136 httpUrlConn.setDoOutput(true); 137 httpUrlConn.setDoInput(true); 138 httpUrlConn.setUseCaches(false); 139 // 設置請求方式(GET/POST) 140 httpUrlConn.setRequestMethod(requestMethod); 141 142 if ("GET".equalsIgnoreCase(requestMethod)) 143 httpUrlConn.connect(); 144 145 // 當有數據須要提交時 146 if (null != outputStr) { 147 OutputStream outputStream = httpUrlConn.getOutputStream(); 148 // 注意編碼格式,防止中文亂碼 149 outputStream.write(outputStr.getBytes("UTF-8")); 150 outputStream.close(); 151 } 152 153 // 將返回的輸入流轉換成字符串 154 InputStream inputStream = httpUrlConn.getInputStream(); 155 InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); 156 BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 157 158 String str = null; 159 while ((str = bufferedReader.readLine()) != null) { 160 buffer.append(str); 161 } 162 bufferedReader.close(); 163 inputStreamReader.close(); 164 // 釋放資源 165 inputStream.close(); 166 inputStream = null; 167 httpUrlConn.disconnect(); 168 log.debug("https buffer:" + buffer.toString()); 169 } catch (ConnectException ce) { 170 log.error("Weixin server connection timed out."); 171 } catch (Exception e) { 172 log.error("https request error:{}", e); 173 } 174 return buffer.toString(); 175 } 176 }
1 package com.swpu.o2o.util.weixin; 2 3 import java.security.cert.CertificateException; 4 import java.security.cert.X509Certificate; 5 6 import javax.net.ssl.X509TrustManager; 7 8 /** 9 * 證書信任管理器(用於https請求) 10 * 11 * 12 */ 13 public class MyX509TrustManager implements X509TrustManager { 14 15 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 16 } 17 18 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 19 } 20 21 public X509Certificate[] getAcceptedIssuers() { 22 return null; 23 } 24 }
輸入網址測試成功:
https://open.weixin.qq.com/connect/oauth2/authorizeappid=你的app_id&redirect_uri=你的網址接口&role_type=1&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect
查看Tomcat日誌獲取到相關信息:./apache-tomcat-8.5.41/logs/webapps/debug.log