微信jsSDK 开发网页应用总结 java 端

闲暇时间对这两天的工作做一个总结,也是一个备忘录

一、个人测试公众号开通

访问http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login,用自己的微信号登录,注册一个测试公众号(拥有所有权限)。

二、个人本地项目内网穿透映射 ,推荐使 用natapp,https://natapp.cn/ 

 备注: 官网新手文档(https://natapp.cn/article/natapp_newbie)

  新手注 端口号不要改 默认80 

  tomcat 用户<Context path="" docBase="wxProject" debug="0" reloadable="true"/> 配置默认打开项目

三、项目代码及配置


域名为内网穿透映射的域名 wxServlet 代码如下

 

package com.wx.web.servlet;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet(urlPatterns="/WxServlet")
public class WxServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5826089535002664715L;

	/**
	 * Token可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)
	 */
	private final String TOKEN = "wxzyh";

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		System.out.println("开始校验签名");
		/**
		 * 接收微信服务器发送请求时传递过来的4个参数
		 */
		String signature = request.getParameter("signature");// 微信加密签名signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
		String timestamp = request.getParameter("timestamp");// 时间戳
		String nonce = request.getParameter("nonce");// 随机数
		String echostr = request.getParameter("echostr");// 随机字符串
		// 排序
		String sortString = sort(TOKEN, timestamp, nonce);
		// 加密
		String mySignature = sha1(sortString);
		// 校验签名
		if (mySignature != null && mySignature != ""
				&& mySignature.equals(signature)) {
			System.out.println("签名校验通过。");
			// 如果检验成功输出echostr,微信服务器接收到此输出,才会确认检验完成。
			// response.getWriter().println(echostr);
			response.getWriter().write(echostr);
		} else {
			System.out.println("签名校验失败.");
		}

	}

	/**
	 * 排序方法
	 *
	 * @param token
	 * @param timestamp
	 * @param nonce
	 * @return
	 */
	public String sort(String token, String timestamp, String nonce) {
		String[] strArray = { token, timestamp, nonce };
		Arrays.sort(strArray);
		StringBuilder sb = new StringBuilder();
		for (String str : strArray) {
			sb.append(str);
		}

		return sb.toString();
	}

	/**
	 * 将字符串进行sha1加密
	 *
	 * @param str
	 *            需要加密的字符串
	 * @return 加密后的内容
	 */
	public String sha1(String str) {
		try {
			MessageDigest digest = MessageDigest.getInstance("SHA-1");
			digest.update(str.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 "";
	}

}
 token 超时处理,servlet init 线程处理,每隔(7000*1000)重新获取 相关代码如下

package com.wx.web.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wx.web.common.ConfigUtil;
import com.wx.web.util.NetWorkHelper;



@WebServlet(
         name = "InitTokenServlet",
         urlPatterns = {"/InitTokenServlet"},
         loadOnStartup = 1
         )
public class InitTokenServlet extends HttpServlet {
	/**
	 * 
	 */
	private static final long serialVersionUID = 6331264937014187299L;

	@Override
	public void init() throws ServletException {
		
		System.out.println("启动WebServlet");
		super.init();
		final String appId = ConfigUtil.APPID;

		final String appSecret = ConfigUtil.APP_SECRET;
		
		new Thread(new Runnable(){

			@Override
			public void run() {
				while(true){
					try {
						
						String token = getAccessToken(appId, appSecret);
						
						if(token!=null){
							ConfigUtil.ACCESS_TOKEN = token;
							getTicket(token);
							Thread.sleep(7000*1000);
						}else{
							Thread.sleep(1000*3);
						}
					} catch (Exception e) {
						System.out.println("发生异常:"+e.getMessage());
						e.printStackTrace();
						try {
							Thread.sleep(1000*1);
						} catch (Exception e2) {
							// TODO: handle exception
						}
					}
				}
				
			}
			
		}).start();
	}
	
	private String  getAccessToken(String appId,String appSecret){
		NetWorkHelper netHelper = new NetWorkHelper();
		String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appId, appSecret);
		String result = netHelper.getHttpsResponse(url, "");
		System.out.println("获取到的access_token="+result);
		JSONObject json = JSON.parseObject(result);
		String accesstoken = json.getString("access_token");		
		return accesstoken;
		
	}
	
	private void getTicket(String token){
		NetWorkHelper netHelper = new NetWorkHelper();
		String url = String.format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi",  token);
		String result = netHelper.getHttpsResponse(url, "");
		System.out.println("获取到的ticket="+result);
		JSONObject json = JSON.parseObject(result);
		String ticket =  json.getString("ticket");
		ConfigUtil.JSAPI_TICKET = ticket;
	}
}
package com.wx.web.common;

public class ConfigUtil {
	public static final String APPID = "xxxxxxxxx"; 
	public static final String APP_SECRET = "xxxxxxxxxxxxxxxx";
	public static final String GRANT_TYPE = "client_credential";
	public static final String JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
	public static final String JSAPI_TICKET_TYPE = "jsapi";
	public static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";

	
	public static String ACCESS_TOKEN = "";
	public static String JSAPI_TICKET = "";

}
给页面提供参数的servlet JSON 返回

package com.wx.web.servlet;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

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 com.alibaba.fastjson.JSONObject;
import com.wx.web.common.ConfigUtil;


@WebServlet(urlPatterns="/WxConfigServlet")
public class WxConfigServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8577082499121279011L;
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		doPost(req, resp);
		
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String url = req.getParameter("url");
		Map<String,Object> data = new HashMap<String, Object>();
		String nonce_str = createNoncestr();
        String timestamp = createTimestamp();
        String string1;
        String signature = "";
        //注意这里参数名必须全部小写,且必须有序
        string1 = "jsapi_ticket=" + ConfigUtil.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();
        }
        data.put("url", url);
        data.put("jsapi_ticket", ConfigUtil.JSAPI_TICKET);
        data.put("nonceStr", nonce_str);
        data.put("timestamp", timestamp);
        data.put("signature", signature);
        data.put("appId", ConfigUtil.APPID);
//		ConfigUtil.NONCESTR = 
//		super.doPost(req, resp);
        resp.setContentType("application/json; charset=utf-8");  
        resp.setCharacterEncoding("UTF-8");  
  
        String userJson = JSONObject.toJSONString(data);  
        OutputStream out = resp.getOutputStream();  
        out.write(userJson.getBytes("UTF-8"));  
        out.flush();  

	}
	
	protected String createNoncestr() {
		return UUID.randomUUID().toString();
	}
	protected String  createTimestamp() {
		return Long.toString(System.currentTimeMillis()/1000);
		
	}
	
	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;
    }
	
	
	
	
	
	

}
页面获取

<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
		<title>线下转账</title>
		<link rel="stylesheet" type="text/css" href="../css/aui/aui.css" />
		<!--<link rel="stylesheet" type="text/css" href="../css/style.css" />-->
		<style>
			.txt_money {
				color: #e74c3c;
				font-weight: bold;
				padding: 0 4px;
			}
			select.sj_select {
				font-size: 12px !important;
				padding: 6px 0 6px 15px !important;
				color: #666 !important;
			}
			.txt_money {
				color: #e74c3c;
				font-weight: bold;
				padding: 0 4px;
			}
			.ptb {
				padding: 2px 12px !important;
			}
			.zzxx .aui-list-item-input{color:#CC4D03}
		</style>
	</head>
	<body>
		
		
	</body>
	
	<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js" type="text/javascript" ></script>
	
	
	<script>
		wxConfig();
		
		
		
		
		
		/**
		  * 微信配置接口
		  * @returns
		  */		 		
		function wxConfig(){
			var url = window.location.href;
			$.post('/wxZyh/WxConfigServlet', { url: url }, function(ret){
				
				  var appId = ret.appId;
				  var timestamp = ret.timestamp;
				  var nonceStr = ret.nonceStr;
				  var signature = ret.signature;
				  
				  wx.config({
					    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
					    appId: appId, // 必填,公众号的唯一标识
					    timestamp: timestamp, // 必填,生成签名的时间戳
					    nonceStr: nonceStr, // 必填,生成签名的随机串
					    signature: signature,// 必填
					    jsApiList: ['chooseImage','previewImage','uploadImage','downloadImage','getLocalImgData'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
				  });
				  
			});

			
		}
		
	</script>
</html>






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值