阿里云部署Java网站和微信开发调试心得技巧

阿里云部署Java网站和微信开发调试心得技巧(上)

阿里云部署Java网站和微信开发调试心得技巧(上)
本篇手记旨在帮助大家从0开始:

  1. 申请阿里云服务器
  2. 搭建出程序的执行环境
  3. 在服务器上发布并运行自己的web project
  4. 域名解析
  5. 微信测试号的申请与连接以获取微信用户信息
    全篇文章主要以如何去完成目标为主,因此会以流程的形式来展现,细节方面需要大家多多思考。其中文章的上集实现了1-4,文章的下集实现了5
    一、申请阿里云服务器
    (1)PC访问阿里云https://www.aliyun.com/,申请阿里云帐号(可以用您的支付宝帐号登录,因为支付宝帐号已经进行了实名认证,使用起来更方便)并登录
    (2)找到云服务器ECS购买页面(页面展现随时会变,当前为全部导航->产品->弹性计算->云服务器ECS->选择自己需要的型号(我选择的是入门级)),购买云服务器,这里主要有三种方式:9块9的学生服务器(大家如果不是学生的话可以用还在读大学的小伙伴的学生证来薅羊毛,购买)、包年包月的服务器(不管你怎么使用,按年按月收费)还有按量付费的服务器(按小时计费,不用可以随时注销掉)
    阿里云部署Java网站和微信开发调试心得技巧
    操作系统记得选择centos,这里我用的是最新的7.3版本
    阿里云部署Java网站和微信开发调试心得技巧
    上半部分的安全设置里面需要填写上root的登录密码,以后咱们需要用这个root帐号来远程登录服务器去做部署,下半部分主要显示的是您选择的阿里云清单
    阿里云部署Java网站和微信开发调试心得技巧
    开通成功后,服务器会启动并运行,同时会自动分配一个公网IP,咱们外网就可以通过这个公网IP访问服务器,同时也可以将域名解析到这个服务器中。
    阿里云部署Java网站和微信开发调试心得技巧
    这里翔仔的公网IP为47.104.1.235
    二、搭建程序的执行环境
    搭建程序的执行环境,咱们先列一下常用的执行环境清单:
    (1) JDK(这里选择的是JDK1.8)
    下载地址为
    http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
    选择的是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
    (3) Mysql(这里选择的是Mysql5.7)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
    将上面的软件都下载到本地,并上传到服务器(如果您的系统为MAC或LINUX,直接使用SCP命令行上传,具体指令可以查询网上,如果您的系统为WIN,推荐使用filezilla可视化上传工具上传),或者您也可以直接登录服务器,wget+ftp地址直接下载这些软件;同时需要大家注意的是,我们在服务器上部署了数据库之后,需要往数据库里面去补充数据,我们的线上数据访问的是线上的数据库而非本地的数据库。图片包也需要上传到服务器并通过配置server.xml确保能读取到这些图片(前提是docBase配置上的路径已经在服务器上创建)
    阿里云部署Java网站和微信开发调试心得技巧
    可以在阿里云控制台进入终端
    阿里云部署Java网站和微信开发调试心得技巧
    在服务器的终端,正确的情况下就能看到这些软件了。
    阿里云部署Java网站和微信开发调试心得技巧
    接下来开始安装这些软件:
  6. 安装JDK
    Java程序需要运行在JRE里边,因此咱们需要安装JDK,在软件路径里执行
    //添加可执行权限
    chmod +x jdk-8u144-linux-x64.rpm
    //安装RPM软件包
    rpm -ivh jdk-8u144-linux-x64.rpm
    //查看java的版本信息,若出现版本信息则成功
    java –version
    阿里云部署Java网站和微信开发调试心得技巧
  7. 安装Mysql
    安装用来配置mysql的yum源的rpm包
    rpm -Uvh mysql57-community-release-el7-11.noarch.rpm
    安装Mysql
    yum install mysql-community-server
    阿里云部署Java网站和微信开发调试心得技巧
    开启mysql服务
    service mysqld start
    阿里云部署Java网站和微信开发调试心得技巧
    mysql安装成功后创建的超级用户’root’@‘localhost’的密码会被存储在/var/log/mysqld.log,可以使用如下命令查看密码
    grep ‘temporary password’ /var/log/mysqld.log
    阿里云部署Java网站和微信开发调试心得技巧
    使用mysql生成的’root’@‘localhost’用户和密码登录数据库,并修改 其密码,具体命令
    mysql -uroot -p
    ALTER USER ‘root’@‘localhost’ IDENTIFIED BY ‘Xiangze230!’;
    阿里云部署Java网站和微信开发调试心得技巧
    开启远程连接
    通过阿里云控制台开放3306端口
    在阿里云控制台咱们的实例页面下面选择安全组->配置规则
    阿里云部署Java网站和微信开发调试心得技巧
    进入到规则配置页面之后,咱们可以看到目前只有22端口和3389端口支持远程访问,咱们还需要额外开通80端口(微信公众号用),3306端口(mysql)以及6379端口(redis)
    阿里云部署Java网站和微信开发调试心得技巧
    配置一个支持远程登录的帐号,这里配置一个work帐号
    mysql -u root -p
    use mysql;
    grant SELECT,UPDATE,INSERT,DELETE on . to ‘work’@’%’ identified by ‘Xiangze230!’;//创建work帐号并授权,同时设置密码
    flush privileges;//生效配置
    之后便能在我们本地通过调用mysql指令远程登录阿里云服务器上的mysql server中,
    mysql -uwork -P3306 -h47.104.1.235 –p //本机远程登录mysql指令
    阿里云部署Java网站和微信开发调试心得技巧
  8. 安装redis
    redis安装真的特别简单,首先先解压redis安装包
    tar -zxvf redis-4.0.2.tar.gz
    设置redis以支持远程登录
    vi redis-4.0.2/redis.conf
    将bind 127.0.0.1这句话用井号注释掉,这样就能支持远程连接了
    阿里云部署Java网站和微信开发调试心得技巧
    此外,还需要给redis.conf添加配置以支持redis作为守护进程一直跑在后台
    需要加入『daemonize yes』
    阿里云部署Java网站和微信开发调试心得技巧
    安装redis
    去到解压后的目录里
    cd redis-4.0.2
    make //安装redis
    启动redis服务
    src/redis-server redis.conf
    阿里云部署Java网站和微信开发调试心得技巧
    redis连接测试
    通过redis-cli连接到redis服务器
    src/redis-cli
    当输入ping 得到pong的回应之后,证明redis配置已经完成
    阿里云部署Java网站和微信开发调试心得技巧
    4.安装tomcat 8
    tomcat 8的安装更为简单
    解压tomcat压缩包
    tar -zxvf apache-tomcat-8.0.46.tar.gz
    启动tomcat
    ./apache-tomcat-8.0.46/bin/startup.sh
    阿里云部署Java网站和微信开发调试心得技巧
    三、在服务器上发布并运行自己的web project
    修改tomcat默认启动端口,从8080修改为80端口,便于微信登录
    vi apache-tomcat-8.0.46/conf/server.xml
    阿里云部署Java网站和微信开发调试心得技巧
    重启tomcat
    ./apache-tomcat-8.0.46/bin/shutdown.sh
    ./apache-tomcat-8.0.46/bin/startup.sh
    修改自己本地的网站的配置
    这里由于大家自己的java网站项目的配置都不相同,只能说大概的,即把项目里的mysql配置(如果有的话),redis配置(如果有的话)修改为阿里云服务器对应的配置(即ip,端口,密码等配置修改成服务器里安装好的这些软件的对应的配置)
    阿里云部署Java网站和微信开发调试心得技巧
    打出自己项目的war包
    阿里云部署Java网站和微信开发调试心得技巧
    阿里云部署Java网站和微信开发调试心得技巧
    阿里云部署Java网站和微信开发调试心得技巧
    将export出来的war包上传到服务器tomcat的webapps目录下
    scp o2o.war [email protected]:/root/apache-tomcat-8.0.46/webapps
    阿里云部署Java网站和微信开发调试心得技巧
    上传成功后,没过几秒tomcat便会在webapps目录下自动从项目war包中解析出项目工程目录来
    阿里云部署Java网站和微信开发调试心得技巧
    之后通过ip+请求路径的形式便能访问到自己的项目(因为已经设置成80端口,这是http默认访问的端口,所以不需要在URL里添加端口信息了)
    阿里云部署Java网站和微信开发调试心得技巧
    四、域名解析
    如果通过ip连接微信号,则总会弹出烦人的警告窗口,因此咱们可以先购买一个域名并对域名进行认证(具体的备案步骤不同服务商有不同要求,大家可以按照他们的要求来,主要分有个人认证和企业认证两种,当然大家如果不嫌烦,可以直接用ip即跳过域名解析这一步),建议大家看看周围的朋友有谁已经有经过验证的域名了,这样可以直接借他的域名创建一个二级域名来用,方便省事,翔仔购买的是阿里云控制台里面的万网域名,购买并认证成功后,会有如下截图,选择购买好的域名并点击解析创建出二级域名
    阿里云部署Java网站和微信开发调试心得技巧
    进入到解析的页面,选择添加解析,并在A记录里面设置好O2O,IP里面设置咱们的阿里云服务器公网IP。这样就能创建出o2o.yitiaojieinfo.com这样的域名指向该公网IP
    阿里云部署Java网站和微信开发调试心得技巧
    隔一段时间,大概5-10分钟这样子,通过域名访问咱们的站点,就能发现访问是okay的

 

五、微信测试号的申请与连接以获取微信用户信息
在咱们自己的程序里面编写servlet以响应微信号
在接下来的步骤中,我们将在测试号里面设置接口配置信息的URL,一经设置,微信公众号便会发请求到我们设置好的URL去,我们必须编写程序应答才能顺利连通微信公众号,因此咱们需要编写相应的响应程序
需要编写两个类
【SignUtil】

 
  1. package com.imooc.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. }

【WechatController】

 
  1. package com.imooc.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.imooc.o2o.util.wechat.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. }

之后重新部署一版最新的程序

访问微信测试号登录页面,通过打开自己手机的微信,扫一扫登录
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
阿里云部署Java网站和微信开发调试心得技巧
进入到测试号页面后,分别看到如下信息
【测试号信息】
appID:开发者ID,是公众号开发识别码,配合开发者密码可以调用微信公众号接口,如获取微信昵称等
appsecret:开发者密码,是检验公众号开发者身份的密码,具有极高的安全性。切记不要把密码交给第三方开发者或者编写到代码里
阿里云部署Java网站和微信开发调试心得技巧
【接口配置信息】
URL: 是开发者用来接收微信消息和事件的接口URL
Token:由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)
阿里云部署Java网站和微信开发调试心得技巧
【JS接口安全域名】
域名:想调用jssdk(如想要通过微信公众号js接口获取地图等工具)必须得填写此域名,在此域名的范围内才能调用jssdk工具,注意这里必须是域名,不是带有http之类的URL,这里直接填写o2o.yitiaojieinfo.com
阿里云部署Java网站和微信开发调试心得技巧
【测试号二维码】
里面包含了测试号二维码以及已经关注了的用户信息
阿里云部署Java网站和微信开发调试心得技巧
【体验接口权限表】
这里主要介绍【网页服务】里面的【网页帐号】
网页帐号主要用来设置OAuth2.0里面的网页授权域名,用户在网页授权页同意授权给公众号后,微信会将授权数据传给一个回调页面,回调页面需在此域名下,以确保安全可靠。沙盒号回调地址支持域名和ip,正式公众号回调地址只支持域名。这里直接设置为o2o.yitiaojieinfo.com
阿里云部署Java网站和微信开发调试心得技巧
阿里云部署Java网站和微信开发调试心得技巧
有不清楚的地方可以直接参考微信官方文档
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319
接下来需要编写自己的程序以获取关注此公众号的用户信息
需要编写5个类 WechatLoginController.java,UserAccessToken.java,WechatUser.java,WechatUtil.java以及MyX509TrustManager.java
【WechatLoginController】主要用来获取已关注此微信号的用户信息并做相应处理

 
  1. package com.imooc.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.imooc.o2o.dto.UserAccessToken;

  15. import com.imooc.o2o.dto.WechatUser;

  16. import com.imooc.o2o.util.wechat.WeiXinUserUtil;

  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. * @author xiangze

  26. *

  27. */

  28. public class WechatLoginController {

  29.  
  30. private static Logger log = LoggerFactory.getLogger(WechatLoginController.class);

  31.  
  32. @RequestMapping(value = "/logincheck", method = { RequestMethod.GET })

  33. public String doGet(HttpServletRequest request, HttpServletResponse response) {

  34. log.debug("weixin login get...");

  35. // 获取微信公众号传输过来的code,通过code可获取access_token,进而获取用户信息

  36. String code = request.getParameter("code");

  37. // 这个state可以用来传我们自定义的信息,方便程序调用,这里也可以不用

  38. // String roleType = request.getParameter("state");

  39. log.debug("weixin login code:" + code);

  40. WechatUser user = null;

  41. String openId = null;

  42. if (null != code) {

  43. UserAccessToken token;

  44. try {

  45. // 通过code获取access_token

  46. token = WeiXinUserUtil.getUserAccessToken(code);

  47. log.debug("weixin login token:" + token.toString());

  48. // 通过token获取accessToken

  49. String accessToken = token.getAccessToken();

  50. // 通过token获取openId

  51. openId = token.getOpenId();

  52. // 通过access_token和openId获取用户昵称等信息

  53. user = WeiXinUserUtil.getUserInfo(accessToken, openId);

  54. log.debug("weixin login user:" + user.toString());

  55. request.getSession().setAttribute("openId", openId);

  56. } catch (IOException e) {

  57. log.error("error in getUserAccessToken or getUserInfo or findByOpenId: " + e.toString());

  58. e.printStackTrace();

  59. }

  60. }

  61. // ======todo begin======

  62. // 前面咱们获取到openId后,可以通过它去数据库判断该微信帐号是否在我们网站里有对应的帐号了,

  63. // 没有的话这里可以自动创建上,直接实现微信与咱们网站的无缝对接。

  64. // ======todo end======

  65. if (user != null) {

  66. // 获取到微信验证的信息后返回到指定的路由(需要自己设定)

  67. return "frontend/index";

  68. } else {

  69. return null;

  70. }

  71. }

  72. }

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

 
  1. package com.imooc.o2o.dto;

  2.  
  3. import com.fasterxml.jackson.annotation.JsonProperty;

  4.  
  5. /**

  6. * 用户授权token

  7. *

  8. * @author xiangze

  9. *

  10. */

  11. public class UserAccessToken {

  12.  
  13. // 获取到的凭证

  14. @JsonProperty("access_token")

  15. private String accessToken;

  16. // 凭证有效时间,单位:秒

  17. @JsonProperty("expires_in")

  18. private String expiresIn;

  19. // 表示更新令牌,用来获取下一次的访问令牌,这里没太大用处

  20. @JsonProperty("refresh_token")

  21. private String refreshToken;

  22. // 该用户在此公众号下的身份标识,对于此微信号具有唯一性

  23. @JsonProperty("openid")

  24. private String openId;

  25. // 表示权限范围,这里可省略

  26. @JsonProperty("scope")

  27. private String scope;

  28.  
  29. public String getAccessToken() {

  30. return accessToken;

  31. }

  32.  
  33. public void setAccessToken(String accessToken) {

  34. this.accessToken = accessToken;

  35. }

  36.  
  37. public String getExpiresIn() {

  38. return expiresIn;

  39. }

  40.  
  41. public void setExpiresIn(String expiresIn) {

  42. this.expiresIn = expiresIn;

  43. }

  44.  
  45. public String getRefreshToken() {

  46. return refreshToken;

  47. }

  48.  
  49. public void setRefreshToken(String refreshToken) {

  50. this.refreshToken = refreshToken;

  51. }

  52.  
  53. public String getOpenId() {

  54. return openId;

  55. }

  56.  
  57. public void setOpenId(String openId) {

  58. this.openId = openId;

  59. }

  60.  
  61. public String getScope() {

  62. return scope;

  63. }

  64.  
  65. public void setScope(String scope) {

  66. this.scope = scope;

  67. }

  68.  
  69. @Override

  70. public String toString() {

  71. return "accessToken:" + this.getAccessToken() + ",openId:" + this.getOpenId();

  72. }

  73.  
  74. }

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

 
  1. package com.imooc.o2o.dto;

  2.  
  3. import java.io.Serializable;

  4.  
  5. import com.fasterxml.jackson.annotation.JsonProperty;

  6.  
  7. /**

  8. * 微信用户实体类

  9. *

  10. * @author xiangze

  11. *

  12. */

  13. public class WechatUser implements Serializable {

  14.  
  15. /**

  16. *

  17. */

  18. private static final long serialVersionUID = -4684067645282292327L;

  19.  
  20. // openId,标识该公众号下面的该用户的唯一Id

  21. @JsonProperty("openid")

  22. private String openId;

  23. // 用户昵称

  24. @JsonProperty("nickname")

  25. private String nickName;

  26. // 性别

  27. @JsonProperty("sex")

  28. private int sex;

  29. // 省份

  30. @JsonProperty("province")

  31. private String province;

  32. // 城市

  33. @JsonProperty("city")

  34. private String city;

  35. // 区

  36. @JsonProperty("country")

  37. private String country;

  38. // 头像图片地址

  39. @JsonProperty("headimgurl")

  40. private String headimgurl;

  41. // 语言

  42. @JsonProperty("language")

  43. private String language;

  44. // 用户权限,这里没什么作用

  45. @JsonProperty("privilege")

  46. private String[] privilege;

  47.  
  48. public String getOpenId() {

  49. return openId;

  50. }

  51.  
  52. public void setOpenId(String openId) {

  53. this.openId = openId;

  54. }

  55.  
  56. public String getNickName() {

  57. return nickName;

  58. }

  59.  
  60. public void setNickName(String nickName) {

  61. this.nickName = nickName;

  62. }

  63.  
  64. public int getSex() {

  65. return sex;

  66. }

  67.  
  68. public void setSex(int sex) {

  69. this.sex = sex;

  70. }

  71.  
  72. public String getProvince() {

  73. return province;

  74. }

  75.  
  76. public void setProvince(String province) {

  77. this.province = province;

  78. }

  79.  
  80. public String getCity() {

  81. return city;

  82. }

  83.  
  84. public void setCity(String city) {

  85. this.city = city;

  86. }

  87.  
  88. public String getCountry() {

  89. return country;

  90. }

  91.  
  92. public void setCountry(String country) {

  93. this.country = country;

  94. }

  95.  
  96. public String getHeadimgurl() {

  97. return headimgurl;

  98. }

  99.  
  100. public void setHeadimgurl(String headimgurl) {

  101. this.headimgurl = headimgurl;

  102. }

  103.  
  104. public String getLanguage() {

  105. return language;

  106. }

  107.  
  108. public void setLanguage(String language) {

  109. this.language = language;

  110. }

  111.  
  112. public String[] getPrivilege() {

  113. return privilege;

  114. }

  115.  
  116. public void setPrivilege(String[] privilege) {

  117. this.privilege = privilege;

  118. }

  119.  
  120. @Override

  121. public String toString() {

  122. return "openId:" + this.getOpenId() + ",nikename:" + this.getNickName();

  123. }

  124. }

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

 
  1. package com.imooc.o2o.util.wechat;

  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.imooc.o2o.dto.UserAccessToken;

  23. import com.imooc.o2o.dto.WechatUser;

  24.  
  25. /**

  26. * 微信工具类

  27. *

  28. * @author xiangze

  29. *

  30. */

  31. public class WechatUtil {

  32.  
  33. private static Logger log = LoggerFactory.getLogger(WechatUtil.class);

  34.  
  35. /**

  36. * 获取UserAccessToken实体类

  37. *

  38. * @param code

  39. * @return

  40. * @throws IOException

  41. */

  42. public static UserAccessToken getUserAccessToken(String code) throws IOException {

  43. // 测试号信息里的appId

  44. String appId = "您的appId";

  45. log.debug("appId:" + appId);

  46. // 测试号信息里的appsecret

  47. String appsecret = "您的appsecret";

  48. log.debug("secret:" + appsecret);

  49. // 根据传入的code,拼接出访问微信定义好的接口的URL

  50. String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appsecret

  51. + "&code=" + code + "&grant_type=authorization_code";

  52. // 向相应URL发送请求获取token json字符串

  53. String tokenStr = httpsRequest(url, "GET", null);

  54. log.debug("userAccessToken:" + tokenStr);

  55. UserAccessToken token = new UserAccessToken();

  56. ObjectMapper objectMapper = new ObjectMapper();

  57. try {

  58. // 将json字符串转换成相应对象

  59. token = objectMapper.readValue(tokenStr, UserAccessToken.class);

  60. } catch (JsonParseException e) {

  61. log.error("获取用户accessToken失败: " + e.getMessage());

  62. e.printStackTrace();

  63. } catch (JsonMappingException e) {

  64. log.error("获取用户accessToken失败: " + e.getMessage());

  65. e.printStackTrace();

  66. } catch (IOException e) {

  67. log.error("获取用户accessToken失败: " + e.getMessage());

  68. e.printStackTrace();

  69. }

  70. if (token == null) {

  71. log.error("获取用户accessToken失败。");

  72. return null;

  73. }

  74. return token;

  75. }

  76.  
  77. /**

  78. * 获取WechatUser实体类

  79. *

  80. * @param accessToken

  81. * @param openId

  82. * @return

  83. */

  84. public static WechatUser getUserInfo(String accessToken, String openId) {

  85. // 根据传入的accessToken以及openId拼接出访问微信定义的端口并获取用户信息的URL

  86. String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openId

  87. + "&lang=zh_CN";

  88. // 访问该URL获取用户信息json 字符串

  89. String userStr = httpsRequest(url, "GET", null);

  90. log.debug("user info :" + userStr);

  91. WechatUser user = new WechatUser();

  92. ObjectMapper objectMapper = new ObjectMapper();

  93. try {

  94. // 将json字符串转换成相应对象

  95. user = objectMapper.readValue(userStr, WechatUser.class);

  96. } catch (JsonParseException e) {

  97. log.error("获取用户信息失败: " + e.getMessage());

  98. e.printStackTrace();

  99. } catch (JsonMappingException e) {

  100. log.error("获取用户信息失败: " + e.getMessage());

  101. e.printStackTrace();

  102. } catch (IOException e) {

  103. log.error("获取用户信息失败: " + e.getMessage());

  104. e.printStackTrace();

  105. }

  106. if (user == null) {

  107. log.error("获取用户信息失败。");

  108. return null;

  109. }

  110. return user;

  111. }

  112.  
  113. /**

  114. * 发起https请求并获取结果

  115. *

  116. * @param requestUrl

  117. * 请求地址

  118. * @param requestMethod

  119. * 请求方式(GET、POST)

  120. * @param outputStr

  121. * 提交的数据

  122. * @return json字符串

  123. */

  124. public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {

  125. StringBuffer buffer = new StringBuffer();

  126. try {

  127. // 创建SSLContext对象,并使用我们指定的信任管理器初始化

  128. TrustManager[] tm = { new MyX509TrustManager() };

  129. SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");

  130. sslContext.init(null, tm, new java.security.SecureRandom());

  131. // 从上述SSLContext对象中得到SSLSocketFactory对象

  132. SSLSocketFactory ssf = sslContext.getSocketFactory();

  133.  
  134. URL url = new URL(requestUrl);

  135. HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();

  136. httpUrlConn.setSSLSocketFactory(ssf);

  137.  
  138. httpUrlConn.setDoOutput(true);

  139. httpUrlConn.setDoInput(true);

  140. httpUrlConn.setUseCaches(false);

  141. // 设置请求方式(GET/POST)

  142. httpUrlConn.setRequestMethod(requestMethod);

  143.  
  144. if ("GET".equalsIgnoreCase(requestMethod))

  145. httpUrlConn.connect();

  146.  
  147. // 当有数据需要提交时

  148. if (null != outputStr) {

  149. OutputStream outputStream = httpUrlConn.getOutputStream();

  150. // 注意编码格式,防止中文乱码

  151. outputStream.write(outputStr.getBytes("UTF-8"));

  152. outputStream.close();

  153. }

  154.  
  155. // 将返回的输入流转换成字符串

  156. InputStream inputStream = httpUrlConn.getInputStream();

  157. InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");

  158. BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

  159.  
  160. String str = null;

  161. while ((str = bufferedReader.readLine()) != null) {

  162. buffer.append(str);

  163. }

  164. bufferedReader.close();

  165. inputStreamReader.close();

  166. // 释放资源

  167. inputStream.close();

  168. inputStream = null;

  169. httpUrlConn.disconnect();

  170. log.debug("https buffer:" + buffer.toString());

  171. } catch (ConnectException ce) {

  172. log.error("Weixin server connection timed out.");

  173. } catch (Exception e) {

  174. log.error("https request error:{}", e);

  175. }

  176. return buffer.toString();

  177. }

  178. }

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

 
  1. package com.imooc.o2o.util.wechat;

  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. * @author xiangze

  12. *

  13. */

  14. public class MyX509TrustManager implements X509TrustManager {

  15.  
  16. public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

  17. }

  18.  
  19. public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

  20. }

  21.  
  22. public X509Certificate[] getAcceptedIssuers() {

  23. return null;

  24. }

  25. }

之后重新打包一个新的war包并发布到服务器tomcat webapps目录下
发布成功后,关注你自己的测试号(即扫描测试号的那个二维码),然后在手机微信里面或者微信开发者工具里访问相应链接:
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
阿里云部署Java网站和微信开发调试心得技巧
之后查看日志信息,便能发现确实能够获取到用户的信息了
阿里云部署Java网站和微信开发调试心得技巧
至此咱们已经从无到有完成了阿里云部署Java网站和微信公众号的开发,文章虽长,但是干货多多,都是傻瓜式的配置,希望大家喜欢。
注意事项:

  1. 由于tomcat咱们没有调优,启动较慢,建议每次重启等待几分钟再去访问,否则会假死,需要kill掉再重启
  2. 经过认证的微信服务号跟测试号其实是一样的,大家可以按照上述去配置


作者: xiangzepro 
链接:http://www.imooc.com/article/20584
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作!