Java微信公众平台开发之生成带参二维码

来源:互联网 发布:指南针炒股软件诈骗 编辑:程序博客网 时间:2024/05/18 02:10

微信官方提供的生成二维码接口得到的是当前公众号的二维码。


目前有2种类型的二维码:
1、临时二维码,是有过期时间的,最长可以设置为在二维码生成后的30天(即2592000秒)后过期,但能够生成较多数量,主要用于帐号绑定等不要求二维码永久保存的业务场景
2、永久二维码,是无过期时间的,但数量较少(目前为最多10万个),主要用于适用于帐号绑定、用户来源统计等场景


参考文档详见https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433542&token=&lang=zh_CN


获取带参数的二维码的过程包括两步,首先创建二维码ticket,然后凭借ticket到指定URL换取二维码,但是得到ticket之前首先获取到access_token。


1.首先创建个access_token的bean

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;}}

2.创建获取accessToken的方法

public class WechatUtil {private static final Logger logger = Logger.getLogger(WechatUtil.class);// 获取access_token的接口地址(GET) 限200(次/天)public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";// 菜单创建(POST) 限100(次/天)public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";/** * 获取access_token *  * @param appid 凭证 * @param appsecret 密钥 * @return */public static AccessToken getAccessToken(String appid, String appsecret) {AccessToken accessToken = null;String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret);JSONObject jsonObject = HttpRequestUtil.httpRequestJSONObject(requestUrl, HttpRequestUtil.GET_METHOD, null);// 如果请求成功if (null != jsonObject) {try {accessToken = new AccessToken();accessToken.setToken(jsonObject.getString("access_token"));accessToken.setExpiresIn(jsonObject.getInt("expires_in"));} catch (JSONException e) {accessToken = null;// 获取token失败   logger.info("获取token失败 errcode:"+jsonObject.getInt("errcode") +",errmsg:"+ jsonObject.getString("errmsg"));}}return accessToken;}}


HttpRequestUtil.的httpRequestJSONObject方法

/**     *      * @param requestUrl  请求地址     * @param requestMethod   请求方式     * @param str 提交的数据     * @return     */    public static JSONObject httpRequestJSONObject(String requestUrl, String requestMethod, String outputStr){        JSONObject jsonObject = null;        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(requestUrl);            HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();            conn.setSSLSocketFactory(ssf);                        conn.setDoOutput(true);            conn.setDoInput(true);            conn.setUseCaches(false);            //设置请求方式            conn.setRequestMethod(requestMethod);                        if (GET_METHOD.equalsIgnoreCase(requestMethod)){             conn.connect();             }                        if(null != outputStr){                OutputStream outputStream = conn.getOutputStream();                outputStream.write(outputStr.getBytes("UTF-8"));                outputStream.close();            }                        //从输入流读取返回内容            InputStream inputStream = conn.getInputStream();            InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"utf-8");            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);                        String str = null;            StringBuffer buffer = new StringBuffer();            while((str = bufferedReader.readLine())!= null){                buffer.append(str);            }                        //释放资源            bufferedReader.close();            inputStreamReader.close();            inputStream.close();            inputStream=null;            conn.disconnect();            jsonObject = JSONObject.fromObject(buffer.toString());                } catch (Exception e) {            //e.printStackTrace();        logger.info("请求异常: "+e.getMessage());         }                return jsonObject;    }


信任管理器MyX509TrustManager,实现方法自己定义

/** * 信任管理器 * @author fjing * */public class MyX509TrustManager implements X509TrustManager {@Overridepublic void checkClientTrusted(X509Certificate[] arg0, String arg1)throws CertificateException {}@Overridepublic void checkServerTrusted(X509Certificate[] arg0, String arg1)throws CertificateException {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return null;}}

3.获取二维码的Ticket


/** * 创建临时带参数二维码 * @param accessToken * @expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 * @param sceneId  场景Id * @return */public WeChatQRCode createTemporaryORCode(String accessToken, String expireSeconds ,int sceneId) {WeChatQRCode weChatQRCode = null;String requestUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";requestUrl = requestUrl.replace("TOKEN", accessToken);//需要提交的JSON数据String outputStr = "{\"expire_seconds\": %d,\"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\":%d}}}";//创建临时带参数二维码JSONObject jsonObject = HttpRequestUtil.httpRequestJSONObject(requestUrl, HttpRequestUtil.POST_METHOD, String.format(outputStr, expireSeconds, sceneId));if(null!=jsonObject){try {weChatQRCode = new WeChatQRCode();weChatQRCode.setTicket(jsonObject.getString("ticket"));weChatQRCode.setExpire_seconds(jsonObject.getInt("expire_seconds"));logger.info("创建临时带参二维码成功,ticket="+weChatQRCode.getTicket()+",expire_seconds="+weChatQRCode.getExpire_seconds());} catch (Exception e) {weChatQRCode = null;String errorMsg = jsonObject.getString("errmsg");logger.info("创建临时带参二维码失败,错误码是="+errorMsg);}}return weChatQRCode;}/** * 创建永久二维码 * @param accessToken * @param sceneId  场景Id * @param sceneStr  场景IdsceneStr * @return *///数字ID用这个{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 123}}}//或者也可以使用以下POST数据创建字符串形式的二维码参数://字符ID用这个{"action_name": "QR_LIMIT_STR_SCENE", "action_info": {"scene": {"scene_str": "hfrunffgha"}}}public String createPermanentORCode(String accessToken, String sceneStr) {String ticket = null;String requestUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";requestUrl = requestUrl.replace("TOKEN", accessToken);String outputStr = "{\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\":{\"scene\": {\"scene_str\":%s}}}";JSONObject jsonObject = HttpRequestUtil.httpRequestJSONObject(requestUrl, HttpRequestUtil.POST_METHOD, String.format(outputStr, sceneStr));if(null!=jsonObject){try {ticket = jsonObject.getString("ticket");logger.info("创建永久带参二维码成功,ticket="+ticket);} catch (Exception e) {String errorCode = jsonObject.getString("errcode");logger.info("创建永久带参二维码失败,错误码是="+errorCode);String errorMsg = jsonObject.getString("errmsg");logger.info("创建永久带参二维码失败,错误信息是="+errorMsg);}}return ticket;}

强烈建议用测试号生成永久的


4.根据ticket直接获取二维码

/** * 通过ticket换取二维码 * ticket正确情况下,是一张图片,可以直接展示或者下载 * @param ticket * @return */public String showQRcode(String ticket) {String showUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";showUrl = showUrl.replace("TICKET", HttpRequestUtil.urlEncode(ticket, "utf-8"));return showUrl;}

得到二维码的URL


5.用户扫描带参数的二维码的处理

如果没有关注的话,用户可以关注公众号,并且会这个场景值就是所谓的参数推送给开发者,参数是EventKey,直接用request获取即可,注意qrscene_的之后才是二维码的参数值

如果已经关注,微信会直接把场景值的扫描事件直接推送给开发者


6.保存二维码到本地,提供下方法

public static void download(String urlString, String filename,String savePath) throws Exception {          // 构造URL          URL url = new URL(urlString);          // 打开连接          URLConnection con = url.openConnection();          //设置请求超时为5s          con.setConnectTimeout(5*1000);          // 输入流          InputStream is = con.getInputStream();                // 1K的数据缓冲          byte[] bs = new byte[1024];          // 读取到的数据长度          int len;          // 输出的文件流         File sf=new File(savePath);         if(!sf.exists()){             sf.mkdirs();         }         OutputStream os = new FileOutputStream(sf.getPath()+"\\"+filename);          // 开始读取          while ((len = is.read(bs)) != -1) {            os.write(bs, 0, len);          }          // 完毕,关闭所有链接          os.close();          is.close();      }   

2 0
原创粉丝点击