Java调用微信扫一扫

时间:2022-07-23
本文章向大家介绍Java调用微信扫一扫,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

公司公众号二次开发需要调用微信扫一扫接口,在网上查了很多相关资料感觉也不是特别的全,在此特意整理一遍资料,供给自己和大家参考,如有相关缺陷请大家指出。

步骤一:绑定域名

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115打开微信官方文档链接,查看接入步骤

注意这个地方填写JS接口安全域名例如域名是https://www.baidu.com/ 填写www.baidu.com即可

步骤二:引入JS文件

页面引入即可 <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

步骤三:通过config接口注入权限验证配置

关键关键关键,重要的事情说三遍,看附录一,重要的是access_token和jsapi_ticket,首先获的access_token然后用获得的access_token再获取jsapi_ticket,最后利用签名算法获得参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分)

签名算法

package com.wx.utils;

import net.sf.json.JSONObject;

import java.io.IOException;
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;

/**
 * 官方给的使用js的验证工具
 * @author Gang_Luo
 *
 */
public class JsSignUtil {
    public static String accessToken = null;

    public static Map<String, String> sign(String url) throws IOException {
        JSONObject accesTokenObject = AuthUtil.doGetJson(Constants.ACCESS_TOKEN_URL);
        String accesToken = (String) accesTokenObject.get("access_token");
        System.out.println("微信返回accesTokenObject"+accesTokenObject);
        JSONObject jsapiTicketObject = AuthUtil.doGetJson("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accesToken + "&type=jsapi");
        String jsapiTicket = (String) jsapiTicketObject.get("ticket");
        System.out.println("微信返回jsapiTicketObject"+jsapiTicketObject);
        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;
        System.out.println("string1="+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("jsapi_ticket", jsapiTicket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        ret.put("appId", "wx1d91459aadf9156e");

        System.out.println("1.ticket(原始)="+jsapiTicket);
        System.out.println("2.url="+ret.get("url"));
        System.out.println("3.jsapi_ticket(处理后)="+ret.get("jsapi_ticket"));
        System.out.println("4.nonceStr="+ret.get("nonceStr"));
        System.out.println("5.signature="+ret.get("signature"));
        System.out.println("6.timestamp="+ret.get("timestamp"));

        return ret;
    }


    /**
     * 随机加密
     * @param hash
     * @return
     */
    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;
    }

    /**
     * 产生随机串--由程序自己随机产生
     * @return
     */
    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    /**
     * 由程序自己获取当前时间
     * @return
     */
    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}
package com.wx.utils;

public class Constants {

    public static final String APP_ID = "对应公众号appid";

    public static final String APP_SECRET = "对应公众号app_secret";

    public static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=对应公众号appid&secret=对应公众号app_secret"; 
import org.apache.http.util.EntityUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URLEncoder;

public class AuthUtil {

    public static JSONObject doGetJson(String url) throws IOException {
        JSONObject jsonObject = null;
        DefaultHttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        HttpResponse response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();
        if(entity != null){
            String result = EntityUtils.toString(entity,"utf-8");
            jsonObject = JSONObject.fromObject(result);
        }
        httpGet.releaseConnection();
        return jsonObject;
    }
}
package com.wx.scan;

import com.wx.utils.AuthUtil;
import com.wx.utils.Constants;
import com.wx.utils.JsSignUtil;
import net.sf.json.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

@Controller
@RequestMapping("/scan/")
public class ScanController {

    private Log log = LogFactory.getLog(this.getClass());

    @RequestMapping("test")
    public Object test(HttpServletRequest request) throws IOException {
        log.info("--------进入了方法-------");
        String url =  request.getRequestURL().toString();
        Map<String, String> sign = JsSignUtil.sign(url);
        ModelAndView mav = new ModelAndView("scan/scan");
        mav.addObject("sign",sign);
        return mav;
    }
}

步骤四:通过ready接口处理成功验证

步骤五:通过error接口处理失败验证

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2018/4/20
  Time: 11:19
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <meta charset="UTF-8">
    <title>扫一扫</title>
    <script type="text/javascript" src="../js/jquery.js"></script>
    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
    <script  type="text/javascript">
        wx.config({
            debug: true,
            appId: '${sign.get("appId")}',
            timestamp:'${sign.get("timestamp")}',
            nonceStr:'${sign.get("nonceStr")}',
            signature:'${sign.get("signature")}',
            jsApiList : [ 'checkJsApi', 'scanQRCode' ]
        });//end_config
        //步骤五
        wx.error(function(res) {
            alert("出错了:" + res.errMsg);
        });
        //步骤四
         wx.ready(function() {
            wx.checkJsApi({
                jsApiList : ['scanQRCode'],
                success : function(res) {
                }
            });

            //扫描二维码
            document.querySelector('#scanQRCode').onclick = function() {
                wx.scanQRCode({
                    needResult : 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
                    scanType : [ "qrCode", "barCode" ], // 可以指定扫二维码还是一维码,默认二者都有
                    success : function(res) {
                        var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
                        //document.getElementById("wm_id").value = result;//将扫描的结果赋予到jsp对应值上
                        alert("扫描成功::扫描码=" + result);
                    }
                });
            };//end_document_scanQRCode

        });//end_ready
    </script>
</head>
<body>
<button id="scanQRCode" >扫描二维码</button>
</body>
</html>

至此微信扫一扫接口就能成功调通了,注意access_token有访问次数限制,自己根据实际情况做好缓存,这里我就没有写了