15158846557 在线咨询 在线咨询
15158846557 在线咨询
所在位置: 首页 > 营销资讯 > 网站运营 > 阿里云部署的Java网站和微信开发调试心得技巧(下)

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

时间:2022-08-06 21:27:01 | 来源:网站运营

时间:2022-08-06 21:27:01 来源:网站运营

阿里云部署的Java网站和微信开发调试心得技巧(下) 五,微信测试号的申请与连接以电子杂志微信用户信息 在咱们自己的程序里面关系编写的servlet以响应微信号 在接下来的步骤中,我们将在测试号里面设置接口配置信息的网址,一经设置,微信公众号便会发请求到我们设置好的URL去,我们必须编写程序应答才能顺利连通微信公众号,因此咱们需要关系编写相应的响应程序 需要关系编写类两个 【SignUtil】

package com.imooc.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; }}【WechatController】

package com.imooc.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.imooc.o2o.util.wechat.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(); } }}之后重新部署一版最新的程序

访问微信测试号登录页面,通过打开自己手机的微信,一扫扫登录 https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

展示进入到测试号页面后,分别看到如下信息 【测试号信息】 APPID:开发者ID,是公众号开发识别码,配合开发者密码可以调用微信公众号接口,如获取微信昵称等 appsecret:开发者密码,是检验公众号开发身份的密码,具有极高的安全性。切记不要把密码交给第三方开发者或者编写到代码里

【接口配置信息】 URL:是开发者用来接收微信消息和事件的接口URL 令牌:由开发者可以任意填写,用作生成签名(该Token会和接口URL中含有Token进行比对,从而验证安全性)

【JS接口安全 域名】域名:想调用jssdk(如想要通过微信公众号js接口获取地图等工具)必须得填写此域名,在此域名的范围内才能调用jssdk工具,注意这里必须是域名,不是带有HTTP之类的URL 直接这里填写回复时http://o2o.yitiaojieinfo.com

【测试号二维码】 里面所有游戏了测试号二维码以及已经关注了的用户信息

【体验接口权限表】 这里主要介绍【|网页服务】里面的【|网页帐号】 |网页帐号主要用来设置的OAuth2.0里面的网页授权域名,用户在网页授权页同意授权给公众号后,微信会将授权数据传给一个回调页面,回调页面需在此域名下,以确保安全可靠。沙盒号回调地址支持域名和IP,正式公众号回调地址只支持域名。直接这里设置为http://o2o.yitiaojieinfo.com

有不清楚的地方可以直接参考微信官方文档 https://mp.weixin.qq.com / wiki?t = resource / res_main&id = mp1421135319 接下来需要编写自己的程序以获取关注此公众号的用户信息 需要编写5个类WechatLoginController.java,UserAccessToken.java,WechatUser.java,WechatUtil.java以及MyX509TrustManager.java 【WechatLoginController】主要用来获取已关注此微信号的用户信息 做相应处理

package com.imooc.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.imooc.o2o.dto.UserAccessToken;import com.imooc.o2o.dto.WechatUser;import com.imooc.o2o.util.wechat.WeiXinUserUtil;@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 进而获取到用户信息 * * @author xiangze * */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 = WeiXinUserUtil.getUserAccessToken(code); log.debug("weixin login token:" + token.toString()); // 通过token获取accessToken String accessToken = token.getAccessToken(); // 通过token获取openId openId = token.getOpenId(); // 通过access_token和openId获取用户昵称等信息 user = WeiXinUserUtil.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; } }}【UserAccessToken】用户的accessToken实体类,用来接收的accessToken以及OpenID的等信息

package com.imooc.o2o.dto;import com.fasterxml.jackson.annotation.JsonProperty;/** * 用户授权token * * @author xiangze * */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(); }}【WechatUser】微信用户实体类,用来接收昵称openid等用户信息

package com.imooc.o2o.dto;import java.io.Serializable;import com.fasterxml.jackson.annotation.JsonProperty;/** * 微信用户实体类 * * @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(); }}【WechatUtil】主要用来提交HTTPS请求给微信获取用户信息

package com.imooc.o2o.util.wechat;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.imooc.o2o.dto.UserAccessToken;import com.imooc.o2o.dto.WechatUser;/** * 微信工具类 * * @author xiangze * */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(); }}【MyX509TrustManager】主要继承X509TrustManager做HTTPS证书信任管理器

package com.imooc.o2o.util.wechat;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import javax.net.ssl.X509TrustManager;/** * 证书信任管理器(用于https请求) * * @author xiangze * */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; }}之后重新打包一个新的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网站和微信公众号的开发,文章虽长,但是干货多多,都是傻瓜式的配置,希望大家喜欢。 注意事项:

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



作者: xiangzepro

链接:http://www.imooc.com/article/20584

来源:慕课网

本文原创发布于慕课网 ,转载请注明出处,谢谢合作!

关键词:技巧,部署

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭