微信扫一扫功能实现

1. scan.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> 
<!DOCTYPE html>
<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<!--依赖文件:微信的JS-SDK源文件-->
<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<title>扫一扫</title>  
</head>  
<body> 

<div style="width:200px; background-color: gray;" id="scanQRCode">
<img src="<c:url value='/image/scan.png'/>" style="width:200px"></img>
</div>


<script type="text/javascript">
$(function(){
var targetUrl = location.href.split('#')[0];
//alert('targetUrl : '+targetUrl)


//配置调用手机微信功能
$.ajax({  
type: "post",  
url: '<%=basePath%>sample.do', 
dataType:"json",  
data:{"targetUrl":targetUrl},
success: function(ret){
//通过config接口注入权限验证配置
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: ret.appId, // 必填,企业号的唯一标识,此处填写企业号corpid
timestamp: ret.timestamp, // 必填,生成签名的时间戳
nonceStr: ret.nonceStr, // 必填,生成签名的随机串
signature: ret.signature,// 必填,签名,见附录1
jsApiList: ['scanQRCode','chooseImage'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 ,配置多个时用英文逗号“,”隔开。
});

}
});
});

$("#scanQRCode").click(function(){
    wx.scanQRCode({
        desc: 'scanQRCode desc',
        //本人测试发现0适用于二维码,1适用于一维码;
        needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
        scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有
        success: function (res) {         
    //alert(res);  
          var url = res.resultStr; // 商品条形码,取","后面的  
          //alert(res.resultStr)
          if (url.indexOf(",") >= 0) {  
              var tempArray = url.split(',');  
              var tempNum = tempArray[1];  
              alert("条形码 : "+tempNum);
          } else {  
          alert("url.indexOf(',') < 0");
          }  
    },
    error: function(res) {
        if (res.errMsg.indexOf('function_not_exist') > 0) {
            alert('版本过低请升级')
        }
    }
    });  
});

</script>

</body>  
</html>



2. Wx_JS_SDK_Controller.java


package com.want.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.want.util.ServerEnvUtil;
import com.want.util.WeixinUtil;
import com.want.pojo.AccessToken;

import net.sf.json.JSONObject;


@Controller
public class Wx_JS_SDK_Controller {
private static final Logger logger = Logger.getLogger(Wx_JS_SDK_Controller.class);

/**
* 程序入口

* 例如:
* https://open.weixin.qq.com/connect/oauth2/authorize?appid=第三方用户唯一凭证
* &redirect_uri=http://第三方用户域名/项目名/main.do
* &response_type=code&scope=snsapi_base&state=sunlight#wechat_redirect

* @param request
* @param response
* @return
* @throws IOException
*/
@RequestMapping(value = "/main.do") 
public ModelAndView main(HttpServletRequest request, HttpServletResponse response) throws IOException {
ModelAndView mv = new ModelAndView("/scan");
return mv;
}

/**
* js-sdk
*   
* @param request
* @param response
* @throws IOException
*/
@RequestMapping(value = "/sample.do")
public void Sample(HttpServletRequest request, HttpServletResponse response) throws IOException {


JSONObject jsApiTicket = new JSONObject();

// 第三方用户唯一凭证
String appId = 第三方用户唯一凭证;
// 第三方用户唯一凭证密钥
String appSecret = 第三方用户唯一凭证密钥;


// 调用接口获取access_token
AccessToken accessToken = WeixinUtil.getAccessToken(appId, appSecret);

if (null != accessToken) {
jsApiTicket = WeixinUtil.getJsApiTicket(accessToken.getToken());
}

// 注意 URL 一定要动态获取,不能 hardcode
String url = request.getParameter("targetUrl");

Map<String, String> ret = sign(jsApiTicket.get("ticket").toString(), url);

ret.put("appId", appId);

JSONObject oj = JSONObject.fromObject(ret);

PrintWriter out = response.getWriter();
out.print(oj);
out.flush();
out.close();
};

public  Map<String, String> sign(String jsapi_ticket, String url) {
        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写,且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
                  "&noncestr=" + nonce_str +
                  "&timestamp=" + timestamp +
                  "&url=" + url;

        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("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);

        return ret;
    }

private  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  String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    private  String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }


}


3. WerxinUtil.java


package com.want.util;


import java.io.BufferedReader;
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.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.want.pojo.AccessToken;

import net.sf.json.JSONObject;


@Component
public class WeixinUtil {

private static final Logger logger = Logger.getLogger(WeixinUtil.class);
/**
* 发起https请求并获取结果

* @param requestUrl
*          请求地址
* @param requestMethod
*          请求方式(GET、POST)
* @param outputStr
*          提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {

JSONObject jsonObject = null;
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(null, requestUrl, new sun.net.www.protocol.https.Handler());
// 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();
jsonObject = JSONObject.fromObject(buffer.toString());
}
catch (ConnectException ce) {
ce.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
return jsonObject;
}


/**
* 获取access_token

* @param appid
*          凭证
* @param appsecret
*          密钥
* @return AccessToken
*/
public static  AccessToken getAccessToken(String appid, String appsecret) {

AccessToken accessToken = null;

String ACCESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=APPID&corpsecret=APPSECRET";

String requestUrl = ACCESS_TOKEN_URL
.replace("APPID", appid)
.replace("APPSECRET", appsecret);

JSONObject jsonObject = httpRequest(requestUrl, "GET", null);

// 如果请求成功
if (null != jsonObject) {
try {
accessToken = new AccessToken();
accessToken.setToken(jsonObject.getString("access_token"));
accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
}
catch (Exception e) {
accessToken = null;
}
}

return accessToken;
}


public static String js_api_url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKEN";


  /** 
   * 获取jsApiTicket
   *  
   * @param accessToken 有效的access_token 
   */ 
  public static JSONObject getJsApiTicket(String accessToken) {  
    
      // 拼装url  
      String url = js_api_url.replace("ACCESS_TOKEN", accessToken); 
      
      return httpRequest(url, "POST", null);  
    
  } 
 

4. MyX509TrustManager.java


package com.want.util;


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 {  
    }  
    //返回受信任的x509证书数组
    public X509Certificate[] getAcceptedIssuers() {  
        return null;  
    }  
}  


5. AccessToken.java


package com.want.pojo;

/** 
 * 微信通用接口凭证 
 *  
 */  
public class AccessToken {  
    // 获取到的凭证  
    private String token;  
    // 凭证有效时间,单位:秒  
    private int expiresIn;  
  
    public String getToken() {  
        return token;  
    }  
  
    public void setToken(String token) {  
        this.token = token;  
    }  
  
    public int getExpiresIn() {  
        return expiresIn;  
    }  
  
    public void setExpiresIn(int expiresIn) {  
        this.expiresIn = expiresIn;  
    }  
}  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值