摘要:开发背景最近在学习,所以从网上看了一些别人的代码,再加入了自己的一些理解,主要是担心之后会忘记,所以写下一篇东西记录一下思路。
开发背景
最近在学习java,所以从网上看了一些别人的代码,再加入了自己的一些理解,主要是担心之后会忘记,所以写下一篇东西记录一下思路。
一、 获取acess_token以及jsapiTicket新建一个类TokenThread,实现线程的Runnable接口,代码如下:
TokenThread
package util; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.google.gson.Gson; import model.AccessToken; import model.JsapiTicket; /** * Created by xu on 2017/7/10. */ public class TokenThread implements Runnable { public static String appId = "xxx"; public static String appSecret= "xxx"; public static AccessToken accessToken = null; public static JsapiTicket jsapiTicket = null; public final static String js_api_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi"; @Override public void run() { while (true) { try { accessToken = this.getAccessToken(); jsapiTicket = this.getJsapiTicket(); //获取到accessToken后,休眠7000秒,保证不会重复的获取,超过了每天的最大次数 if (null != accessToken) { System.out.println(accessToken.getAccessToken()); System.out.println(jsapiTicket.getJsapiTicket()); Thread.sleep(7000 * 1000); //获取到access_token 休眠7000秒 } else { Thread.sleep(1000 * 3); //获取的access_token为空 休眠3秒 } } catch (Exception e) { System.out.println("发生异常:" + e.getMessage()); e.printStackTrace(); try { Thread.sleep(1000 * 10); //发生异常休眠1秒 } catch (Exception e1) { } } } } /** * 获取access_token * @return */ private AccessToken getAccessToken(){ NetWorkHelper netHelper = new NetWorkHelper(); String Url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",this.appId,this.appSecret); String result = netHelper.getHttpsResponse(Url,""); System.out.println(result); //response.getWriter().println(result); JSONObject json = JSONObject.parseObject(result); System.out.println(json); AccessToken token = new AccessToken(); token.setAccessToken(json.getString("access_token")); token.setExpiresin(json.getInteger("expires_in")); return token; } /** * 获取jsapi_ticket * @return */ private JsapiTicket getJsapiTicket(){ NetWorkHelper netHelper = new NetWorkHelper(); String Url = js_api_ticket_url.replace("ACCESS_TOKEN",this.getAccessToken().getAccessToken()); String result = netHelper.getHttpsResponse(Url,""); System.out.println(result); JSONObject json = JSONObject.parseObject(result); System.out.println(json); JsapiTicket jsapiTicket = new JsapiTicket(); jsapiTicket.setJsapiTicket(json.getString("ticket")); jsapiTicket.setExpiresin(json.getInteger("expires_in")); return jsapiTicket; } }
这里用到了两个工具类NetWorkHelper,发起网络请求网上有封装好的,我做一下搬运工:
NetWorkHelper
package util; import javax.net.ssl.*; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; /** * Created by xu on 2017/7/10. */ public class NetWorkHelper { public String getHttpsResponse(String hsUrl,String requestMethod) { URL url; InputStream is = null; String resultData = ""; try { url = new URL(hsUrl); HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); TrustManager[] tm = {xtm}; SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(null, tm, null); con.setSSLSocketFactory(ctx.getSocketFactory()); con.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String arg0, SSLSession arg1) { return true; } }); con.setDoInput(true); //允许输入流,即允许下载 //在android中必须将此项设置为false con.setDoOutput(false); //允许输出流,即允许上传 con.setUseCaches(false); //不使用缓冲 if(null!=requestMethod && !requestMethod.equals("")) { con.setRequestMethod(requestMethod); //使用指定的方式 } else{ con.setRequestMethod("GET"); //使用get请求 } is = con.getInputStream(); //获取输入流,此时才真正建立链接 InputStreamReader isr = new InputStreamReader(is); BufferedReader bufferReader = new BufferedReader(isr); String inputLine = ""; while ((inputLine = bufferReader.readLine()) != null) { resultData += inputLine + " "; } System.out.println(resultData); Certificate[] certs = con.getServerCertificates(); int certNum = 1; for (Certificate cert : certs) { X509Certificate xcert = (X509Certificate) cert; } } catch (Exception e) { e.printStackTrace(); } return resultData; } X509TrustManager xtm = new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { // TODO Auto-generated method stub return null; } @Override public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { // TODO Auto-generated method stub } @Override public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { // TODO Auto-generated method stub } }; }
上面还引入了阿里巴巴的json解析包import com.alibaba.fastjson.JSONObject;自行上网搜索就好。
上面的获取accessToken的过程中,new了一个AccessToken和JsapiTicket对象,我把她们放进了一个model类里。
AccessToken
package model; /** * Created by xu on 2017/7/10. */ public class AccessToken { public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public int getExpiresin() { return expiresin; } public void setExpiresin(int expiresin) { this.expiresin = expiresin; } private String accessToken; private int expiresin; }
JsapiTicket
package model; /** * Created by xu on 2017/7/12. */ public class JsapiTicket { private String jsapiTicket; private int expiresin; public String getJsapiTicket() { return jsapiTicket; } public void setJsapiTicket(String jsapiTicket) { this.jsapiTicket = jsapiTicket; } public int getExpiresin() { return expiresin; } public void setExpiresin(int expiresin) { this.expiresin = expiresin; } }
新建一个HttpServlet,AccessTokenServlet,用来执行获取,初始化的过程中执行,这里需要配置web.xml
web.xml
wechatServlet com.wecahtServlet wechatServlet GetConfigServlet com.GetConfigServlet GetConfigServlet /getConfig ReturnRobotServlet com.ReturnRobotServlet ReturnRobotServlet /doReturn initAccessTokenServlet com.AccessTokenServlet appid xxxx appsecret xxxx 0 returnRobot.jsp
AccessTokenServlet
package com; import util.TokenThread; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * Created by xu on 2017/7/10. */ @WebServlet(name = "AccessTokenServlet") public class AccessTokenServlet extends HttpServlet { public void init() throws ServletException { TokenThread.appId = getInitParameter("appid"); //获取servlet初始参数appid和appsecret TokenThread.appSecret = getInitParameter("appsecret"); System.out.println("appid:"+TokenThread.appId); System.out.println("appSecret:"+TokenThread.appSecret); new Thread(new TokenThread()).start(); //启动进程 } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }二、获取jssdk配置
创建一个GetConfigServlet用以页面获取jssdk的配置信息
GetConfigServlet
package com; import com.alibaba.fastjson.JSON; import util.Sign; import util.TokenThread; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; /** * Created by xu on 2017/7/12. */ @WebServlet(name = "GetConfigServlet") public class GetConfigServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String url = request.getParameter("url"); String jsapi_tickec = TokenThread.jsapiTicket.getJsapiTicket(); Mapjssdk = Sign.main(jsapi_tickec,url); String str = JSON.toJSONString(jssdk); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); PrintWriter out = null; try { out = response.getWriter(); out.write(str); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { out.close(); } } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("get config test success"); } }
上文中引用了sign工具类:
Sign
package util; import java.util.UUID; import java.util.Map; import java.util.HashMap; import java.util.Formatter; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.io.UnsupportedEncodingException; public class Sign { public static Mapmain(String jsapiTicket,String posturl) { String jsapi_ticket = jsapiTicket; // 注意 URL 一定要动态获取,不能 hardcode String url = posturl; Map ret = sign(jsapi_ticket, url); // for (Map.Entry entry : ret.entrySet()) { // System.out.println(entry.getKey() + ", " + entry.getValue()); // } return ret; }; public static Map sign(String jsapi_ticket, String url) { Map ret = new HashMap (); String nonce_str = create_nonce_str(); String timestamp = create_timestamp(); String string1; String signature = ""; //注意这里参数名必须全部小写,且必须有序 string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "×tamp=" + timestamp + "&url=" + url; System.out.println(string1); try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(string1.getBytes("UTF-8")); signature = byteToHex(crypt.digest()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } ret.put("url", url); ret.put("appId", TokenThread.appId); ret.put("jsapi_ticket", jsapi_ticket); ret.put("nonceStr", nonce_str); ret.put("timestamp", timestamp); ret.put("signature", signature); return ret; } private static String byteToHex(final byte[] hash) { Formatter formatter = new Formatter(); for (byte b : hash) { formatter.format("%02x", b); } String result = formatter.toString(); formatter.close(); return result; } private static String create_nonce_str() { return UUID.randomUUID().toString(); } private static String create_timestamp() { return Long.toString(System.currentTimeMillis() / 1000); } }
前段js:
$(document).ready(function () { //获取配置信息 $.ajax({ url : "http://120.77.43.103/wechat/getConfig", type : "post", dataType : "json", contentType : "application/x-www-form-urlencoded; charset=utf-8", data : { "url" : location.href.split("#")[0] }, success : function(data) { console.log(data); wx.config({ debug : true, appId : data.appId, timestamp : data.timestamp, nonceStr : data.nonceStr, signature : data.signature, jsApiList : [ "checkJsApi", "onMenuShareTimeline", "onMenuShareAppMessage", "onMenuShareQQ", "onMenuShareWeibo", "hideMenuItems", "showMenuItems", "hideAllNonBaseMenuItem", "showAllNonBaseMenuItem", "translateVoice", "startRecord", "stopRecord", "onRecordEnd", "playVoice", "pauseVoice", "stopVoice", "uploadVoice", "downloadVoice", "chooseImage", "previewImage", "uploadImage", "downloadImage", "getNetworkType", "openLocation", "getLocation", "hideOptionMenu", "showOptionMenu", "closeWindow", "scanQRCode", "chooseWXPay", "openProductSpecificView", "addCard", "chooseCard", "openCard" ] }); }, error: function (xhr, type) { showAlert("getJSSDKSignature出错"); }, }); checkUserDeposit(); }); function checkUserDeposit() { wx.ready(function () { scanQRCode(); }); } function scanQRCode() { wx.scanQRCode({ needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果, scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有 success: function (res) { var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果 //var result = "linuxserl.honeybot.cn:5120/download/?id=bind@104@10V1BLH100040478054"; //var result = "CODE_128,10V1BLH100261"; var postCode = ""; var robotCodeType = 0; if (result.indexOf(",") > -1) { //条形码 var codes = result.split(","); if (codes != null && codes.length > 1) { postCode = codes[1]; robotCodeType = 1; } } else { //二维码 var reg = /@(.*?)@/; var codes = reg.exec(result); if (codes.length > 1) { postCode = codes[1]; robotCodeType = 0; } } showConfirm("是否确认退还?", function () { returnRobot(robotCodeType, postCode); }); } }); } function returnRobot(robotCodeType, robotCodeValue) { var dialogLoading = null; var postData = { robot_code: { robot_code_type: robotCodeType, robot_code_value: robotCodeValue } } $.ajax({ type: "POST", cache: false, url: "http://120.77.43.103/wechat/doReturn", data: "json_body=" + JSON.stringify(postData), dataType: "json", beforeSend: function (XHR) { dialogLoading = showLoading(); }, success: function (data) { if (data.result_code == 0) { setTimeout(function() { showAlert("申请退还机器人成功,请点击确定支付租金", function () { goTo(config.page_url.return_robot_wait_confrm); }); }, 500); } else { setTimeout(function () { showAlert(data.result_message); }, 500); } }, error: function (xhr, type) { showAlert("error") }, complete: function (xhr, type) { dialogLoading.hide(); } }); } wx.error(function (res) { showAlert("微信接口出错"); });三、额外的一些签名,验证配置
wecahtServlet
package com; import com.sun.tools.classfile.Signature; import util.CheckUtil; import util.Sign; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * Created by xu on 2017/7/10. */ @WebServlet(name = "wecahtServlet") public class wecahtServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String signature = request.getParameter("signature"); String timestamp = request.getParameter("timestamp"); String nonce = request.getParameter("nonce"); String echostr = request.getParameter("echostr"); if( CheckUtil.checkSignature(signature,timestamp,nonce)) { response.getWriter().println(echostr); } } }
工具类CheckUtil
package util; import java.util.Arrays; /** * Created by xu on 2017/7/10. */ public class CheckUtil { private static final String token = "test"; public static boolean checkSignature(String signature,String timestamp,String nonce) { String[] arr = new String[]{token,timestamp,nonce}; //排序 Arrays.sort(arr); //生成字符串 StringBuffer content = new StringBuffer(); for (int i=0;isha1
package util; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * Created by xu on 2017/7/10. */ public class Decript { public static String SHA1(String decript) { try { MessageDigest digest = MessageDigest .getInstance("SHA-1"); digest.update(decript.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexString = new StringBuffer(); // 字节数组转换为 十六进制 数 for (int i = 0; i < messageDigest.length; i++) { String shaHex = Integer.toHexString(messageDigest[i] & 0xFF); if (shaHex.length() < 2) { hexString.append(0); } hexString.append(shaHex); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } }引用JdbcUtils jdbc连接工具类
package util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class JdbcUtils { private static String url="jdbc:mysql://xxx.xxx.xxx/weixin?useUnicode=true&characterEncoding=utf-8"; private static String user="xxx"; private static String password="xxx"; private JdbcUtils() { } static { try { Class.forName("com.mysql.jdbc.Driver"); } catch(ClassNotFoundException e) { throw new ExceptionInInitializerError(e); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, user, password); } public static void free(ResultSet resultset,Statement st,Connection conn) { //6.释放资源 try{ if(resultset!=null) resultset.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { if(st!=null) st.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if(conn!=null) try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }完整项目地址:https://github.com/345632699/...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/70268.html
摘要:最近做个移动端的应用,要实现自定义微信分享功能,实现过程中遇到一些小小的坑,这里分享一下。后来微信放出了,开始对端提供丰富强大的官方接口支持,也逐渐淡出了开发者的视野。 最近做个移动端的H5应用,要实现自定义微信分享功能,实现过程中遇到一些小小的坑,这里分享一下。 以前微信官方是没有正式支持微信分享的自定义接口(包括图片、标题、描述)的,然而有一些大神找到了WeixinJSBridge...
摘要:最近做个移动端的应用,要实现自定义微信分享功能,实现过程中遇到一些小小的坑,这里分享一下。后来微信放出了,开始对端提供丰富强大的官方接口支持,也逐渐淡出了开发者的视野。 最近做个移动端的H5应用,要实现自定义微信分享功能,实现过程中遇到一些小小的坑,这里分享一下。 以前微信官方是没有正式支持微信分享的自定义接口(包括图片、标题、描述)的,然而有一些大神找到了WeixinJSBridge...
摘要:主要是用,每当用户第一次进来时,去获取一次签名验证。注意只获取一次,这样签名就解决了。 vue+微信支付目录+JSSDK签名解决方案 遇坑如下 注意:此方法仅为个人总结,并非唯一解决方案 微信JSSDK签名出错 微信支付 调起支付缺少API参数 微信支付目录配置,只有5个配置,可能超过5个地方有配置,路由规划 微信授权回调处理 我所使用的技术 vue路由模式 history 模...
摘要:签名用的必须是调用接口页面的完整。出于安全考虑,开发者必须在服务器端实现签名的逻辑。以上为服务器的步骤,根据以上内容实现了一个简单的中间件,详见客户端使用接口注入权限验证配置待续 关键名词解释 安全域名: 用于JSSDK,开发者即可在该域名(包括二级域名)下调用微信开放的JS接口 access_token: · 普通access_token:JSSDK和微信公众号后台...
阅读 1959·2021-10-13 09:39
阅读 3390·2021-09-30 09:52
阅读 778·2021-09-26 09:55
阅读 2757·2019-08-30 13:19
阅读 1866·2019-08-26 10:42
阅读 3169·2019-08-26 10:17
阅读 524·2019-08-23 14:52
阅读 3611·2019-08-23 14:39