java-微信公众号h5调起扫一扫
目录
需要一个微信公众号-服务号
公众号设置==>功能设置
.txt文件下载放在项目根目录
域名为h5的访问域名 列如 www.baidu.com
appId 写自己公众号的appId
access_token为当前公众号的access_token,不知道怎么获取access_token的朋友可以看https://blog.****.net/u013008827/article/details/89085133
在这里我是把access_token放到了redis中,access_token的有效期为两个小时,起个定时任务,一个半小时更新一次
package com.kj.utils.wxQRCode;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.URL;
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.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.kj.common.Constants;
import com.kj.util.RedisCache;
import com.kj.utils.PropertiesUtil;
import com.kj.utils.SpringContextUtils;
import net.sf.json.JSONObject;
public class WxShare {
private static Log logger = LogFactory.getLog(WxShare.class);
@Autowired
private static RedisCache redisCache;
@Autowired
private static PropertiesUtil propertiesUtil;
static{
if(redisCache==null){
redisCache = (RedisCache)SpringContextUtils.getBean("redisCache");
}
if(propertiesUtil==null){
propertiesUtil = (PropertiesUtil)SpringContextUtils.getBean("proUtil");
}
}
/**
* 方法名:httpRequest
* 详述:发送http请求
* 开发人员:zjw
* 创建时间:2016-1-5
* @param requestUrl
* @param requestMethod
* @param outputStr
* @return 说明返回值含义
* @throws 说明发生此异常的条件
*/
public static JSONObject httpRequest(String requestUrl,String requestMethod, String outputStr) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
try {
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
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);
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();
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
ce.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return jsonObject;
}
/**
* 方法名:byteToHex
* 详述:字符串加密辅助方法
* 开发人员:zjw
* 创建时间:2016-1-5
* @param hash
* @return 说明返回值含义
* @throws 说明发生此异常的条件
*/
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;
}
public static Map<String, Object> getWxConfig(HttpServletRequest request, String reqUrl){
logger.info("进入微信配置信息,开始获取参数"+request.getParameterMap());
Map<String, Object> map = new HashMap<String, Object>();
String appId = propertiesUtil.getAppId(); // 必填,公众号的唯一标识
String access_token = (String) redisCache.select(Constants.REDISKEY_ACCESS_TOKEN);
String jsapi_ticket = "";
String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填,生成签名的时间戳
String nonceStr = UUID.randomUUID().toString(); // 必填,生成签名的随机串
if (access_token != null) {
String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token + "&type=jsapi";
JSONObject json = httpRequest(url, "GET", null);
if (json != null) {
jsapi_ticket = json.getString("ticket");
logger.info("进入微信分享接口,参数jsapi_ticket为:"+jsapi_ticket);
}
}
String signature = "";
// 注意这里参数名必须全部小写,且必须有序
String sign = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr+ "×tamp=" + timestamp + "&url=" + reqUrl;
logger.info("请求路径:"+sign);
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(sign.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
map.put("appId", appId);
map.put("timestamp", timestamp);
map.put("nonceStr", nonceStr);
map.put("signature", signature);
return map;
}
}
引入js文件
<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta content="initial-scale=1.0,user-scalable=no,maximum-scale=1,width=device-width" name="viewport" />
<meta content="yes" name="apple-mobile-web-app-capable" />
<meta content="black" name="apple-mobile-web-app-status-bar-style" />
<meta content="telephone=no" name="format-detection" />
<title>口令支付</title>
<link rel="stylesheet" type="text/css" href="css/basic.css" />
<link rel="stylesheet" type="text/css" href="css/style.css" />
</head>
<body style="background: #f8f1f1;">
<section class="my_view">
<div class="top-key"><a class="goback" href="javascript:history.go(-1);"><img src="img/o-arr-b.png"></a><span class="tit">口令支付</span></div>
<div class="keypay-c">
<div class="tipc">输入口令</div>
<div class="intdiv"><input type="text" placeholder="请输入口令" id="wordNum" onkeyup="this.value=this.value.replace(/\s+/g,'')"></div>
<div class="btndiv"><button class="btn-go" id="subgo">立即使用</button></div>
<div class="btndiv"><button class="btn-go" id="scanQRCode">扫码使用口令</button></div>
<div class="tipc2">请输入您获得的口令字符,立即使用,即可支付</div>
</div>
<div class="tc-qx" id="alert">
<p class="pc1">?</p>
<p class="psub"><a class="subBtn">确定</a></p>
</div>
<div class="modal-overlay" style=""></div>
</section>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/base.js"></script>
<script type="text/javascript" src="js/checkMsg.js"></script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script type="text/javascript">
(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
if(clientWidth>=750){
docEl.style.fontSize = '100px';
}else{
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
}
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
</script>
<script>
//弹窗 模拟alert
function showMask(msg){
$('.tc-qx').each(function(){
var w_height = $(window).height();
var this_height = $(this).height();
$(this).css("top",(w_height-this_height)/2.5);
});
$('.modal-overlay').css({"visibility":"visible","opacity":"1"});
$('#alert').css({"visibility":"visible","opacity":"1"});
$('#alert .pc1').empty().text(msg);
$('#alert .subBtn').click(function(){closeMask()});
}
function closeMask(){
$('.modal-overlay').css({"visibility":"hidden","opacity":"0"});
$('#alert').css({"visibility":"hidden","opacity":"0"});
}
//showMask('哈哈哈哈');
//截取URL 获取
function GetQueryString(name){
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if(r!=null)return unescape(r[2]); return null;
};
var reportId=GetQueryString("reportId");
var packageId=GetQueryString("packageId");
var userId=GetQueryString("userId");
var openId=GetQueryString("openId");
var edition=GetQueryString("edition"); //判断用哪一版页面显示首页
if(edition==null){
edition = '';
};
var reqUrl = window.location.href;
<script>
$.ajax({
type:"post",
url: dataUrl+ "/weiXin/wxConfig",
data:{
reqUrl: reqUrl
},
success:function(result){
wx.config({
// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
debug: false,
// 必填,公众号的唯一标识
appId: result.wxParameter.appId,
// 必填,生成签名的时间戳
timestamp:""+result.wxParameter.timestamp,
// 必填,生成签名的随机串
nonceStr:result.wxParameter.nonceStr,
// 必填,签名,见附录1
signature:result.wxParameter.signature,
// 必填,需要使用的JS接口列表,所有JS接口列表见附录2
jsApiList : [ 'checkJsApi', 'scanQRCode' ]
});
}
})
wx.error(function(res) {
alert("出错了:" + res.errMsg);//这个地方的好处就是wx.config配置错误,会弹出窗口哪里错误,然后根据微信文档查询即可。
});
wx.ready(function() {
wx.checkJsApi({
jsApiList : ['scanQRCode'],
success : function(res) {
}
});
//点击按钮扫描二维码
document.querySelector('#scanQRCode').onclick = function() {
wx.scanQRCode({
needResult : 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
scanType : [ "qrCode"], // 可以指定扫二维码还是一维码,默认二者都有
success : function(res) {
var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
//window.location.href = result;//因为我这边是扫描后有个链接,然后跳转到该页面
alert("二维码内容为:" + result)
}
});
};
});
</script>
</body>
</html>