服务器部署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】:
package com.swpu.o2o.util.weixin; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays; /**
* 微信请求校验工具类
*/
public class SignUtil {
// 与接口配置信息中的Token要一致
private static String token = "myo2o"; /**
* 验证签名
*
* @param signature
* @param timestamp
* @param nonce
* @return
*/
public static boolean checkSignature(String signature, String timestamp, String nonce) {
String[] arr = new String[] { token, timestamp, nonce };
// 将token、timestamp、nonce三个参数进行字典序排序
Arrays.sort(arr);
StringBuilder content = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
content.append(arr[i]);
}
MessageDigest md = null;
String tmpStr = null; try {
md = MessageDigest.getInstance("SHA-1");
// 将三个参数字符串拼接成一个字符串进行sha1加密
byte[] digest = md.digest(content.toString().getBytes());
tmpStr = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} content = null;
// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
} /**
* 将字节数组转换为十六进制字符串
*
* @param byteArray
* @return
*/
private static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
} /**
* 将字节转换为十六进制字符串
*
* @param mByte
* @return
*/
private static String byteToHexStr(byte mByte) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
char[] tempArr = new char[2];
tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr);
return s;
}
}
微信请求Controller【WeChatController】:
package com.swpu.o2o.web.wechat; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import com.swpu.o2o.util.weixin.SignUtil; @Controller
//一会在设置的URL里面就设置上这个路由
@RequestMapping("wechat")
public class WechatController { private static Logger log = LoggerFactory.getLogger(WechatController.class); @RequestMapping(method = { RequestMethod.GET })
public void doGet(HttpServletRequest request, HttpServletResponse response) {
log.debug("weixin get...");
// 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
String signature = request.getParameter("signature");
// 时间戳
String timestamp = request.getParameter("timestamp");
// 随机数
String nonce = request.getParameter("nonce");
// 随机字符串
String echostr = request.getParameter("echostr"); // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
PrintWriter out = null;
try {
out = response.getWriter();
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
log.debug("weixin get success....");
out.print(echostr);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null)
out.close();
}
}
}
配置成功:
【JS接口安全域名】
域名:想调用jssdk(如想要通过微信公众号js接口获取地图等工具)必须得填写此域名,在此域名的范围内才能调用jssdk工具,注意这里必须是域名(IP),不是带有http之类的URL
【测试号二维码】
里面包含了测试号二维码以及已经关注了的用户信息(微信号扫码)
【体验接口权限表】
有很多权限可以使用如下:
这里主要介绍【网页服务】里面的【网页帐号】
网页帐号主要用来设置OAuth2.0里面的网页授权域名,用户在网页授权页同意授权给公众号后,微信会将授权数据传给一个回调页面,回调页面需在此域名下,以确保安全可靠。沙盒号回调地址支持域名和ip,正式公众号回调地址只支持域名。
2.获取关注此公众号的用户信息(修改后记得重新打包上传到服务器):
2.1【WechatLoginController】主要用来获取已关注此微信号的用户信息并做相应处理
package com.swpu.o2o.web.wechat; import java.io.IOException; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import com.swpu.o2o.dto.UserAccessToken;
import com.swpu.o2o.dto.WechatUser;
import com.swpu.o2o.util.weixin.WechatUtil; @Controller
@RequestMapping("wechatlogin")
/**
* 获取关注公众号之后的微信用户信息的接口,如果在微信浏览器里访问
* 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
* 则这里将会获取到code,之后再可以通过code获取到access_token 进而获取到用户信息
*
*
*/
public class WechatLoginController { private static Logger log = LoggerFactory.getLogger(WechatLoginController.class); @RequestMapping(value = "/logincheck", method = { RequestMethod.GET })
public String doGet(HttpServletRequest request, HttpServletResponse response) {
log.debug("weixin login get...");
// 获取微信公众号传输过来的code,通过code可获取access_token,进而获取用户信息
String code = request.getParameter("code");
// 这个state可以用来传我们自定义的信息,方便程序调用,这里也可以不用
// String roleType = request.getParameter("state");
log.debug("weixin login code:" + code);
WechatUser user = null;
String openId = null;
if (null != code) {
UserAccessToken token;
try {
// 通过code获取access_token
token = WechatUtil.getUserAccessToken(code);
log.debug("weixin login token:" + token.toString());
// 通过token获取accessToken
String accessToken = token.getAccessToken();
// 通过token获取openId
openId = token.getOpenId();
// 通过access_token和openId获取用户昵称等信息
user = WechatUtil.getUserInfo(accessToken, openId);
log.debug("weixin login user:" + user.toString());
request.getSession().setAttribute("openId", openId);
} catch (IOException e) {
log.error("error in getUserAccessToken or getUserInfo or findByOpenId: " + e.toString());
e.printStackTrace();
}
}
// ======todo begin======
// 前面咱们获取到openId后,可以通过它去数据库判断该微信帐号是否在我们网站里有对应的帐号了,
// 没有的话这里可以自动创建上,直接实现微信与咱们网站的无缝对接。
// ======todo end======
if (user != null) {
// 获取到微信验证的信息后返回到指定的路由(需要自己设定)
return "frontend/index";
} else {
return null;
}
}
}
2.1.1用户信息表及Dao层:
package com.swpu.o2o.entity; import java.util.Date; public class PersonInfo {
/*
* 用户信息表
*/
private Long userId;
private String name;
private String profileImg;
private String email;
private String gender;
private Integer enableStatus;
// 1.顾客 2.店家 3.超级管理员
private Integer userType;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProfileImg() {
return profileImg;
}
public void setProfileImg(String profileImg) {
this.profileImg = profileImg;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Integer getEnableStatus() {
return enableStatus;
}
public void setEnableStatus(Integer enableStatus) {
this.enableStatus = enableStatus;
}
public Integer getUserType() {
return userType;
}
public void setUserType(Integer userType) {
this.userType = userType;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getLastEditTime() {
return lastEditTime;
}
public void setLastEditTime(Date lastEditTime) {
this.lastEditTime = lastEditTime;
}
private Date createTime;
private Date lastEditTime; }
package com.swpu.o2o.dao; import com.swpu.o2o.entity.PersonInfo; public interface PersonInfoDao {
/**
* 通过用户Id查询用户
* @param userId
* @return
*/
PersonInfo queryPersonInfoById(long userId);
/**
* 添加新用户
* @param personInfo
* @return
*/
int insertPersonInfo(PersonInfo personInfo);
}
2.1.2微信相关信息表Dao层:
package com.swpu.o2o.entity; import java.util.Date; public class WechatAuth {
/*
* 微信登录表
*/
private Long wechatAuthId;
private String openId;
private Date createTime;
private PersonInfo personInfo;
private Long userId;
public Long getWechatAuthId() {
return wechatAuthId;
}
public void setWechatAuthId(Long wechatAuthId) {
this.wechatAuthId = wechatAuthId;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public PersonInfo getPersonInfo() {
return personInfo;
}
public void setPersonInfo(PersonInfo personInfo) {
this.personInfo = personInfo;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
}
package com.swpu.o2o.dao; import com.swpu.o2o.entity.WechatAuth; public interface WechatAuthDao {
/**
* 通过openId查询对应本平台的微信号
* @param openId
* @return
*/
WechatAuth queryWechatInfoByOpenId(String openId);
/**
* 添加对应本平台的微信号
* @param wechatAuth
* @return
*/
int insertWechatAuth(WechatAuth wechatAuth);
}
2.1.3用户信息接口,微信信息接口对应Mybatis:
用户:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.swpu.o2o.dao.PersonInfoDao">
<select id="queryPersonInfoById" resultType="com.swpu.o2o.entity.PersonInfo"
parameterType="Long">
SELECT
user_id,name,gender,email,profile_img,enable_status,user_type,create_time,last_edit_time
FROM tb_person_info where user_id=#{userId}
</select>
<insert id="insertPersonInfo" parameterType="com.swpu.o2o.entity.PersonInfo"
useGeneratedKeys="true" keyProperty="userId" keyColumn="user_id">
INSERT INTO
tb_person_info(name,gender,email,profile_img,user_type,create_time,last_edit_time,enable_status)
VALUES(#{name},#{gender},#{email},#{profileImg},#{userType},#{createTime},#{lastEditTime},#{enableStatus}) </insert>
</mapper>
微信信息:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.swpu.o2o.dao.WechatAuthDao">
<resultMap id="wechatAuthResultMap" type="com.swpu.o2o.entity.WechatAuth">
<id property="wechatAuthId" column="wechat_auth_id" />
<result property="userId" column="user_id" />
<result property="openId" column="open_id" />
<result property="createTime" column="create_time" />
<association property="personInfo" column="user_id"
javaType="com.swpu.o2o.entity.PersonInfo">
<id property="userId" column="user_id" />
<result property="name" column="name" />
<result property="gender" column="gender" />
<result property="phone" column="phone" />
<result property="email" column="email" />
<result property="createTime" column="create_time" />
<result property="lastEditTime" column="last_edit_time" />
<result property="enableStatus" column="enable_status" />
</association>
</resultMap>
<select id="queryWechatInfoByOpenId" parameterType="String"
resultMap="wechatAuthResultMap"> SELECT w.wechat_auth_id, w.user_id, w.open_id,
w.create_time, p.user_id, p.name, p.gender,
p.email, p.profile_img, p.create_time, p.last_edit_time, p.enable_status FROM
tb_wechat_auth w LEFT JOIN tb_person_info p ON w.user_id = p.user_id
WHERE w.open_id = #{openId}
</select>
<insert id="insertWechatAuth" parameterType="com.swpu.o2o.entity.WechatAuth"
keyColumn="wechat_auth_id" keyProperty="wechatAuthId"
useGeneratedKeys="true"> INSERT INTO
tb_wechat_auth(user_id,open_id,create_time) VALUES
(#{userId},#{openId},#{createTime})
</insert>
<delete id="deleteWechatAuth"> DELETE FROM tb_wechat_auth WHERE wechat_auth_id =
#{wechatAuthId}
</delete>
</mapper>
2.2【UserAccessToken】用户AccessToken实体类,用来接收accesstoken以及openid等信息
package com.swpu.o2o.dto; import com.fasterxml.jackson.annotation.JsonProperty; /**
* 用户授权token
*
*
*/
public class UserAccessToken { // 获取到的凭证
@JsonProperty("access_token")
private String accessToken;
// 凭证有效时间,单位:秒
@JsonProperty("expires_in")
private String expiresIn;
// 表示更新令牌,用来获取下一次的访问令牌,这里没太大用处
@JsonProperty("refresh_token")
private String refreshToken;
// 该用户在此公众号下的身份标识,对于此微信号具有唯一性
@JsonProperty("openid")
private String openId;
// 表示权限范围,这里可省略
@JsonProperty("scope")
private String scope; public String getAccessToken() {
return accessToken;
} public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
} public String getExpiresIn() {
return expiresIn;
} public void setExpiresIn(String expiresIn) {
this.expiresIn = expiresIn;
} public String getRefreshToken() {
return refreshToken;
} public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
} public String getOpenId() {
return openId;
} public void setOpenId(String openId) {
this.openId = openId;
} public String getScope() {
return scope;
} public void setScope(String scope) {
this.scope = scope;
} @Override
public String toString() {
return "accessToken:" + this.getAccessToken() + ",openId:" + this.getOpenId();
} }
2.3【WechatUser】微信用户实体类,用来接收昵称 openid等用户信息
package com.swpu.o2o.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable; /**
* 微信用户实体类
*
* @author xiangze
*
*/
public class WechatUser implements Serializable { /**
*
*/
private static final long serialVersionUID = -4684067645282292327L; // openId,标识该公众号下面的该用户的唯一Id
@JsonProperty("openid")
private String openId;
// 用户昵称
@JsonProperty("nickname")
private String nickName;
// 性别
@JsonProperty("sex")
private int sex;
// 省份
@JsonProperty("province")
private String province;
// 城市
@JsonProperty("city")
private String city;
// 区
@JsonProperty("country")
private String country;
// 头像图片地址
@JsonProperty("headimgurl")
private String headimgurl;
// 语言
@JsonProperty("language")
private String language;
// 用户权限,这里没什么作用
@JsonProperty("privilege")
private String[] privilege; public String getOpenId() {
return openId;
} public void setOpenId(String openId) {
this.openId = openId;
} public String getNickName() {
return nickName;
} public void setNickName(String nickName) {
this.nickName = nickName;
} public int getSex() {
return sex;
} public void setSex(int sex) {
this.sex = sex;
} public String getProvince() {
return province;
} public void setProvince(String province) {
this.province = province;
} public String getCity() {
return city;
} public void setCity(String city) {
this.city = city;
} public String getCountry() {
return country;
} public void setCountry(String country) {
this.country = country;
} public String getHeadimgurl() {
return headimgurl;
} public void setHeadimgurl(String headimgurl) {
this.headimgurl = headimgurl;
} public String getLanguage() {
return language;
} public void setLanguage(String language) {
this.language = language;
} public String[] getPrivilege() {
return privilege;
} public void setPrivilege(String[] privilege) {
this.privilege = privilege;
} @Override
public String toString() {
return "openId:" + this.getOpenId() + ",nikename:" + this.getNickName();
}
}
2.4【WechatUtil】主要用来提交https请求给微信获取用户信息
package com.swpu.o2o.util.weixin; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL; import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.swpu.o2o.dto.UserAccessToken;
import com.swpu.o2o.dto.WechatUser; /**
* 微信工具类
*
*/
public class WechatUtil { private static Logger log = LoggerFactory.getLogger(WechatUtil.class); /**
* 获取UserAccessToken实体类
*
* @param code
* @return
* @throws IOException
*/
public static UserAccessToken getUserAccessToken(String code) throws IOException {
// 测试号信息里的appId
String appId = "您的appId";
log.debug("appId:" + appId);
// 测试号信息里的appsecret
String appsecret = "您的appsecret";
log.debug("secret:" + appsecret);
// 根据传入的code,拼接出访问微信定义好的接口的URL
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appsecret
+ "&code=" + code + "&grant_type=authorization_code";
// 向相应URL发送请求获取token json字符串
String tokenStr = httpsRequest(url, "GET", null);
log.debug("userAccessToken:" + tokenStr);
UserAccessToken token = new UserAccessToken();
ObjectMapper objectMapper = new ObjectMapper();
try {
// 将json字符串转换成相应对象
token = objectMapper.readValue(tokenStr, UserAccessToken.class);
} catch (JsonParseException e) {
log.error("获取用户accessToken失败: " + e.getMessage());
e.printStackTrace();
} catch (JsonMappingException e) {
log.error("获取用户accessToken失败: " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
log.error("获取用户accessToken失败: " + e.getMessage());
e.printStackTrace();
}
if (token == null) {
log.error("获取用户accessToken失败。");
return null;
}
return token;
} /**
* 获取WechatUser实体类
*
* @param accessToken
* @param openId
* @return
*/
public static WechatUser getUserInfo(String accessToken, String openId) {
// 根据传入的accessToken以及openId拼接出访问微信定义的端口并获取用户信息的URL
String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openId
+ "&lang=zh_CN";
// 访问该URL获取用户信息json 字符串
String userStr = httpsRequest(url, "GET", null);
log.debug("user info :" + userStr);
WechatUser user = new WechatUser();
ObjectMapper objectMapper = new ObjectMapper();
try {
// 将json字符串转换成相应对象
user = objectMapper.readValue(userStr, WechatUser.class);
} catch (JsonParseException e) {
log.error("获取用户信息失败: " + e.getMessage());
e.printStackTrace();
} catch (JsonMappingException e) {
log.error("获取用户信息失败: " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
log.error("获取用户信息失败: " + e.getMessage());
e.printStackTrace();
}
if (user == null) {
log.error("获取用户信息失败。");
return null;
}
return user;
} /**
* 发起https请求并获取结果
*
* @param requestUrl
* 请求地址
* @param requestMethod
* 请求方式(GET、POST)
* @param outputStr
* 提交的数据
* @return json字符串
*/
public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
StringBuffer buffer = new StringBuffer();
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl);
HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
// 设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod); if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect(); // 当有数据需要提交时
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
} // 将返回的输入流转换成字符串
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
log.debug("https buffer:" + buffer.toString());
} catch (ConnectException ce) {
log.error("Weixin server connection timed out.");
} catch (Exception e) {
log.error("https request error:{}", e);
}
return buffer.toString();
}
}
2.5【MyX509TrustManager】主要继承X509TrustManager做https证书信任管理器
package com.swpu.o2o.util.weixin; import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; /**
* 证书信任管理器(用于https请求)
*
*
*/
public class MyX509TrustManager implements X509TrustManager { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
} public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
} public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
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
服务器部署Java Web及微信开发调试的更多相关文章
- 阿里云服务器部署Java Web项目全过程
最近需要将一个Java Web项目部署到服务器上,方便多人共享访问.这也是我第一次接触服务器之类的东西,也花了一点时间,最终总算部署成功,写下一篇文章记录以便日后回顾. 购买服务器 第一步当然是需要购 ...
- 记录第一次阿里云服务器部署java web工程的经历
起因:测试一个微信小程序,发现所有的请求要求为https的形式,开发工具忽略后手机无法测试,故尝试配置. 准备:阿里云服务器一台 域名一个(解析在服务器) tomcat7.0.54 j ...
- 阿里云windows 2012服务器部署java web程序教程
一:环境搭建 1.首先需要购买一个阿里云ECS服务器,购买时可以选择处理器核数以及内存大小(可以购买偏低配置,因为升级 方便) 2.购买后会自动创建一个实例,可以使用该实例中显示的公网地址在 ...
- 【转】Tomcat中部署java web应用程序
http://www.blogjava.net/jiafang83/archive/2009/06/02/279644.html 转载:今天给大家介绍怎样在Tomcat5.5.9中部署Java Web ...
- 在Tomcat中部署Java Web应用程序
在Tomcat中部署Java Web应用程序有两种方式:静态部署和动态部署.在下文中$CATALINA_HOME指的是Tomcat根目录. 一.静态部署 静态部署指的是我们在服务器启动之前部 ...
- 新手小白Linux(Centos6.5)部署java web项目(总)
一.准备 1.linux centos版本的相关命令操作,千万别找ubuntu的,好多命令都不一样,新手小白我傻傻不知道硬是浪费了一天的时间……(百度百科linux版本了解一下) 2.远程登录: P ...
- Tomcat中部署Java Web应用程序的方式
Tomcat中部署Java Web应用程序的几种方式: #PetWeb是工程名 1.在TOMCAT_HOME\conf\server.xml文件的HOST节点中加入 <Context docBa ...
- Linux CentOS下部署Java Web项目
本文讲解如何在Linux CentOS下部署Java Web项目的步骤. 一.环境准备: (1)Linux CentOS (2)apache-tomcat-9.0.10 (3)XShell 二.启动t ...
- 在Tomcat中部署Java Web应用程序几种方式
在Tomcat中部署Java Web应用程序有两种方式:静态部署和动态部署.在下文中$CATALINA_HOME指的是Tomcat根目录. 一.静态部署 静态部署指的是我们在服务器启动之前部 ...
随机推荐
- zookeeper系列(一)zookeeper图形化的客户端工具
追加一个zookeeper图形化的客户端工具: 1.zookeeper图像化客户端工具的下载地址:https://issues.apache.org/jira/secure/attachment/12 ...
- 20175215 2018-2019-2 第九周java课程学习总结
第十一章 JDBC与MySQL数据库 11.1 MySQL数据库管理系统 下载安装过程略 使用的是MySQL 5.6而非5.7 11.2 启动MySQL数据库服务器 启动和root用户过程略 11.3 ...
- Android Butterknife(黄油刀) 使用方法总结
前言: ButterKnife是一个专注于Android系统的View注入框架,以前总是要写很多findViewById来找到View对象,有了ButterKnife可以很轻松的省去这些步骤.是大神J ...
- matplotlib展现混淆矩阵
1.展现混淆矩阵 import matplotlib.pyplot as plt import itertools def plot_confusion_matrix(cm, classes, tit ...
- js前台传数组,java后台接收转list,前后台用正则校验
前台,传参数时,将数组对象转换成json串,后台java收到后用 JSONArray.fromObject 转成集合. 前台js:var params = {"FileNameList&qu ...
- c# Selenium ExpectedConditions 不存在
Selenium中的显示等待指的是,等待某一元素出现或者等待页面加载完成后,才执行下一步.需要用到WebDriverWait类. 例如: , , )); var element = wait.Unti ...
- OO ALV 后台运行时错误:Control Framework: Fatal error - GUI cannot be reached
这个错误的原因,是GUI容器依赖GUI的存在,因为它是在后台运行,没有GUI,因此控制错误. 可以通过做一些编码绕过这个. * ALV Grid DATA: R_GRID TYPE REF TO CL ...
- golang(09) golang 接口内部实现
原文链接 http://www.limerence2017.com/2019/09/24/golang14/#more 前文介绍过golang interface用法,本文详细剖析interface内 ...
- Block代码块中使用局部变量注意点
第一次写代码遇到报这个错,实在是想不通为什么,按常理应该是不会有问题,报错的呀??纠结了一会之后只好仔细查看报错原因咯,原来是: 当我们在block代码块中使用局部变量时,就会很容易出现如图的错误. ...
- C基础知识(10):预处理器
C预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤.简言之,C预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理. 所有的预处理器命令都是以井号(#)开 ...