微信浏览器调起来扫一扫和问题总结

微信浏览器调用扫一扫,需要微信公众号的appid和app_secret
然后微信设置里面设置上,js安全域名和ip白名单即可

1.首先根据appid和secret获得ticket
2.然后获取随机字符串等参与签名
3.返回给h5端掉用扫一扫相关参数

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;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import net.sf.json.JSONObject;

public class Test {
	
	public static String weixin_app_id;
	
    public static String weixin_app_secret;

    public static String mobile_realm_name;
    
    public static void main(String[] args) {
    	//获取签名相关参数
		Map sign = getSign();
		System.out.println(sign);
	}
 
    public static JSONObject doGetJson(String url) throws IOException {
    	System.out.println("请求url:"+url);
        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;
    }
    /**
     * 产生随机串--由程序自己随机产生
     * @return
     */
    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

        /**
         * 由程序自己获取当前时间
         * @return
         */
        private static String create_timestamp() {
            return Long.toString(System.currentTimeMillis() / 1000);
        }
        
        
        
        
        private static JSONObject getTicket() {
        	//System.out.println("进入获取ticket");
        	JSONObject accesTokenObject;
			try {
				String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+weixin_app_id+"&secret="+weixin_app_secret;
				accesTokenObject = doGetJson(ACCESS_TOKEN_URL);
				String accesToken = (String) accesTokenObject.get("access_token");
	           // System.out.println("微信返回accesTokenObject"+accesTokenObject);
	            JSONObject jsapiTicketObject = doGetJson("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accesToken + "&type=jsapi");
	            return jsapiTicketObject;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
            
        }
 
        /**
         * 随机加密
         * @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;
        } 
        /**
         * 	最终获取出签名的相关参数,然后把四个参数给h5端,h5端再浏览器便能调起来微信扫一扫
         * @return
         */
        public static Map getSign()  {
        	Map ret = new HashMap();
        	try {
        		String jsapiTicket = "";
        		Integer expires_in = 0;
            	JSONObject jsapiTicketObject = getTicket();
        		jsapiTicket = (String) jsapiTicketObject.get("ticket");
	            expires_in = (Integer)jsapiTicketObject.get("expires_in");
	            String nonce_str = create_nonce_str();
	            String timestamp = create_timestamp();
	            String string1;
	            String signature = "";
	     
	           //注意这里参数名必须全部小写,且必须有序
	            string1 = "jsapi_ticket=" + jsapiTicket +
	                      "&noncestr=" + nonce_str +
	                      "×tamp=" + timestamp +
	                      "&url=" + mobile_realm_name;
	            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("appId", weixin_app_id);
	            ret.put("nonceStr", nonce_str);
	            ret.put("timestamp", timestamp);
	            ret.put("signature", signature);
	     
        	}catch(Exception e) {
        		e.printStackTrace();
        	}
            return ret;
        }
        
}

问题总结:
mobile_realm_name参数为当地址的url地址比如:
url = “http://mobile.xxx.com/”;
或者
url = url.split("#")[0];
遇到过一个坑,再微信浏览器获取过一次openid后,然后调用扫一扫
总是报错签名错误,然后前端打印url发现
location.href=‘http://mobile.xxx.com/code=dk2313313?#/xxx’;
i地址里面给加了一点参数,导致签名错误
解决办法为:h5端在获取签名参数时候,h5端先获取出当前页面地址
然后把地址传给服务端,服务端截取 “#"号,保留之前的url,然后参与签名
问题便能解决。

你可能感兴趣的:(项目开发)