• 服务器部署Java Web及微信开发调试


    参考摘抄: 

      阿里云部署Java网站和微信开发调试心得技巧(上):https://www.imooc.com/article/20583

      阿里云部署Java网站和微信开发调试心得技巧(下):https://www.imooc.com/article/20584

    一.运行环境搭建(centos上)

      (1) JDK(这里选择的是JDK1.8)    

        下载地址为:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html选择的是jdk-8u144-linux-x64.rpm。

        下载完成后执行:rpm -ivh jdk-8u144-linux-x64.rpm

      (2) Tomcat 8

        下载地址为http://tomcat.apache.org/download-80.cgi#8.0.46选择的是apache-tomcat-8.0.46.tar.gz

        解压:tar -zxvf apache-tomcat-8.5.41.tar.gz 

          

        启动tomcat:./apache-tomcat-8.5.41/bin/startup.sh

        修改Tomcat默认连接端口(8080):apache-tomcat-8.5.41/conf/server.xml

        修改完成后重启Tomcat:(注意查看端口是否开启或被占用)

          关闭Tomcat服务:./apache-tomcat-8.5.41/bin/shutdown.sh

          启动Tomcat服务:./apache-tomcat-8.5.41/bin/startup.sh

    查看Tomcat日志是否启动成功

      (3) Mysql(我用的是Mariadb)repo源,后通过centos自带的yum安装

        下载的地址为https://dev.mysql.com/downloads/repo/yum/这里选择mysql57-community-release-el7-11.noarch.rpm

      (4) Redis(可选,最好预先安装上,这里选择的版本为4.0.2)

        下载地址为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工具使用

    二.在服务器上发布并运行自己的Java web项目  

      1.将项目打包成War包:

        

      2.打包完成后,将war包上传到服务器上/apache-tomcat-8.5.41/webapps下:

    上传成功后,没过几秒tomcat便会在webapps目录下自动从项目war包中解析出项目工程目录来

      3.访问目标Ip和端口成功展示:

        注:可以通过查看IP加端口查看Tomcat是否启动成功,很本机都是一样的。

      4.域名解析:

        由于域名比较贵,作为学生党没敢用。以后用的时候简单配置即可。

    三.微信开发调试 

      1.登录微信公众平台提交相关信息

        登录微信公总开发平台: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 }
    View Code

            微信请求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 }
    View Code

             配置成功:

        【JS接口安全域名】

          域名:想调用jssdk(如想要通过微信公众号js接口获取地图等工具)必须得填写此域名,在此域名的范围内才能调用jssdk工具,注意这里必须是域名(IP),不是带有http之类的URL

        

        【测试号二维码】

          里面包含了测试号二维码以及已经关注了的用户信息(微信号扫码)

        【体验接口权限表】

          有很多权限可以使用如下:


          这里主要介绍【网页服务】里面的【网页帐号】

          网页帐号主要用来设置OAuth2.0里面的网页授权域名,用户在网页授权页同意授权给公众号后,微信会将授权数据传给一个回调页面,回调页面需在此域名下,以确保安全可靠。沙盒号回调地址支持域名和ip,正式公众号回调地址只支持域名。

      2.获取关注此公众号的用户信息(修改后记得重新打包上传到服务器):

          2.1【WechatLoginController】主要用来获取已关注此微信号的用户信息并做相应处理 

     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 }
    View Code
             2.1.1用户信息表及Dao层:
     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 }
    View Code
     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 }
    View Code
            2.1.2微信相关信息表Dao层:
     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 }
    View Code
     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 }
    View Code
            2.1.3用户信息接口,微信信息接口对应Mybatis:

             用户:

     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>
    View Code

             微信信息:

     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>
    View Code

            2.2【UserAccessToken】用户AccessToken实体类,用来接收accesstoken以及openid等信息

     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 }
    View Code

          2.3【WechatUser】微信用户实体类,用来接收昵称 openid等用户信息

      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 }
    View Code

          2.4【WechatUtil】主要用来提交https请求给微信获取用户信息

      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 }
    View Code

          2.5【MyX509TrustManager】主要继承X509TrustManager做https证书信任管理器

     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 }
    View Code

       3.测试:

        3.1到https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html下载对应版本的测试工具:

          3.2使用测试工具:

            输入网址测试成功:

              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

        

     

      

          

        

    
    

        

       

      

      

  • 相关阅读:
    iOS 证书错误 Certificates下面的 App Store and Ad Hoc是灰的?? 点不了
    iOS 发布证书错误 Your build settings specify a provisioning profile with the UUID, no provisioning profile was found
    不能修改“System Roots”钥匙串 即下载的.cer 文件添加不到钥匙串
    修改 “嗨加游-Prefix.pch” 或者 “嗨加游-Info.plist ” 方法
    Java基础1(2015-8-2)
    认识modernizr----前端
    VS2013的C#项目与SQL Server2012无法连接的问题
    安装完SQL Server 2012后,由Windows身份验证设置为混合型的身份验证
    C#项目,在controller文件夹右击鼠标没有“添加控制器”的问题
    复制已存在的数据库结构(不包括库中的数据)
  • 原文地址:https://www.cnblogs.com/lyq-biu/p/10945186.html
Copyright © 2020-2023  润新知