1. 程式人生 > >java實現小程式獲取二維碼(介面B)

java實現小程式獲取二維碼(介面B)

應用場景:

  1. 實際應用場景:比如分享助力、名片分享之類的頁面需要生成二維碼
  2. 為滿足不同需求和場景,小程式提供了三個介面,開發者可挑選適合自己的介面

注意事項:

  1. 介面只能生成已釋出的小程式的二維碼
  2. 介面 A 加上介面 C,總共生成的碼數量限制為 100,000,請謹慎呼叫
  3. 介面 B 呼叫分鐘頻率受限(5000次/分鐘),如需大量小程式碼,建議預生成

小程式生成二維碼兩種樣式:


我這裡因為業務需求選擇的是介面B ,下面是具體實現例項。


準備:

  • 小程式appId
  • 小程式appSecret

第一步:獲取呼叫介面憑證,獲取小程式 asscess_token

請求方式:GET

請求地址:​ GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET ​

請求引數:String grant_type(這裡預設填寫client_credential)

String  appid(你自己的小程式appId)

String  secret(你自己的小程式appSecret)

java程式碼實現:

//獲取access_token
        Map<String, Object> param = new HashMap<>();
        param.put("grant_type", Element.grant_type);
        param.put("appid", appid);
        param.put("secret", secret);
        String result = HttpClientUtil.doGet(Element.GET_ACCESS_TOKEND_URL, param);

        logger.info("獲取access_token返回引數{}:" + result);

        Map<String, Object> resultMap = (Map<String, Object>) JSONUtil.jsonToObject(result, Map.class);
        String accessToken = MapUtils.getString(resultMap, "access_token");

        logger.info("access_token=" + accessToken);

這裡的引數通過定義常量和傳參的方式,傳送請求定義了一個工具類,會在下面附上HttpClientUtil.java

小程式提供的網頁除錯工具除錯該介面也能獲取access_token

使用網頁除錯工具除錯該介面

第二步:獲取二維碼

請求方式:POST

請求地址:POST https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN

請求引數:String access_token(上面第一步獲取的access_token)

String scene(最大32個可見字元)

String page(必須是已經發布的小程式存在的頁面(否則報錯),例如 pages/index/index

int width(二維碼的寬度,預設為 430px,最小 280px,最大 1280px)

boolean auto_color(自動配置線條顏色,如果顏色依然是黑色,則說明不建議配置主色調,預設 false)

Object line_color(auto_color 為 false 時生效,使用 rgb 設定顏色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十進位制表示,預設全 0)

boolean is_hyaline(是否需要透明底色,為 true 時,生成透明底色的小程式碼,預設 false)

java實現 :

//獲取二維碼
        URL url = new URL(Element.QR_CODE_URL + accessToken);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        httpURLConnection.setRequestMethod("POST");// 提交模式
        // conn.setConnectTimeout(10000);//連線超時 單位毫秒
        // conn.setReadTimeout(2000);//讀取超時 單位毫秒
        // 傳送POST請求必須設定如下兩行
        httpURLConnection.setDoOutput(true);
        httpURLConnection.setDoInput(true);
        // 獲取URLConnection物件對應的輸出流
        PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
        // 傳送請求引數
        JSONObject paramJson = new JSONObject();
        paramJson.put("scene", userUuid);
        paramJson.put("page", page);
        paramJson.put("width", Element.width);
        paramJson.put("auto_color", Element.auto_color);
        /**
         * line_color生效
         * paramJson.put("auto_color", false);
         * JSONObject lineColor = new JSONObject();
         * lineColor.put("r", 0);
         * lineColor.put("g", 0);
         * lineColor.put("b", 0);
         * paramJson.put("line_color", lineColor);
         * */

        printWriter.write(paramJson.toString());
        // flush輸出流的緩衝
        printWriter.flush();
        //獲取二維碼檔案流
        InputStream inputStream = httpURLConnection.getInputStream();

        String qrCodePath = String.format(qRCodePath, userUuid);
        if (!uploadService.exsitFile(qrCodePath)) {
            String path = uploadService.uploadIsToOSS(inputStream, qrCodePath);
            IOUtils.closeQuietly(inputStream);
            if (StringUtils.isNotBlank(path)) {
                return imageAddress + "/" + path;
            }
        }
        return imageAddress + "/" + qrCodePath;

這裡已經獲取到二維碼的流了,怎麼處理就看實際需求,我這裡是將流寫到OSS上面返回的OSS上面二維碼地址

HttpClientUtil.java: 

package com.xgt.util;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSONObject;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import okhttp3.*;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import static com.xgt.util.wechat.WxPayUtil.XML;

/**
 * Author:wwei
 * DESC:HttpClient工具類
 */
public class HttpClientUtil {


    private static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

    public static String doGet(String url) {
        // 建立HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        String tempTitle = null;
        try {
            HttpGet httpGet = new HttpGet(url);
            // 執行get請求
            HttpResponse httpResponse;
            httpResponse = closeableHttpClient.execute(httpGet);
            // 獲取響應訊息實體
            HttpEntity entity = httpResponse.getEntity();
            // 判斷響應實體是否為空
            if (entity != null) {
                return EntityUtils.toString(entity, "UTF-8");
            } else {
                return null;
            }
        } catch (Exception e) {
            logger.error(tempTitle);
            logger.error(""+ e);
        } finally {
            try {
                // 關閉流並釋放資源
                closeableHttpClient.close();
            } catch (IOException e) {
                logger.error(""+ e);
            }
        }
        return null;
    }


    public static String doGet(String url, Map<String, Object> params) {
        if(!StringUtils.hasText(url)){
            return "";
        }
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        try {
            if (params != null && !params.isEmpty()) {
                List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
                for (String key : params.keySet()) {
                    pairs.add(new BasicNameValuePair(key, params.get(key).toString()));
                }
                url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, "UTF-8"));
            }
            HttpGet httpGet = new HttpGet(url);
            CloseableHttpResponse response = closeableHttpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            // 判斷響應實體是否為空
            if (entity != null) {
                return EntityUtils.toString(entity, "UTF-8");
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 關閉流並釋放資源
                closeableHttpClient.close();
            } catch (IOException e) {
                logger.error(e.toString());
            }
        }
        return null;
    }


    public static String doPost(RequestObject object) {
        // 建立HttpClientBuilder
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        String tempTitle = null;
        try {
            HttpPost httpPost = new HttpPost(object.toUrl());
            // 執行get請求
            HttpResponse httpResponse;
            httpResponse = closeableHttpClient.execute(httpPost);

            // 獲取響應訊息實體
            HttpEntity entity = httpResponse.getEntity();
            // 判斷響應實體是否為空
            if (entity != null) {
                return EntityUtils.toString(entity, "UTF-8");
            } else {
                return null;
            }
        } catch (Exception e) {
            logger.error(tempTitle);
            logger.error(e.toString());
        } finally {
            try {
                // 關閉流並釋放資源
                closeableHttpClient.close();
            } catch (IOException e) {
                logger.error(e.toString());
            }
        }
        return null;
    }

    public static String doPost(String url,Map<String,Object> map,String charset){
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        try{
            httpClient = new SSLClient();
            httpPost = new HttpPost(url);
            httpPost.addHeader("Content-Type", "application/json");
            httpPost.addHeader("Authorization", "Basic YWRtaW46");
            //設定引數

            String paramStr = JSONUtils.toJSONString(map);
            logger.info("....請求引數:{}....",paramStr);
            StringEntity entity = new StringEntity(paramStr, "utf-8");
            entity.setContentEncoding(new BasicHeader("Content-Type",
                    "application/json"));
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);
            if(response != null){
                HttpEntity resEntity = response.getEntity();
                if(resEntity != null){
                    result = EntityUtils.toString(resEntity,charset);
                }
            }
        }catch(Exception ex){
            ex.printStackTrace();
        }
        logger.info("....返回結果:{}.......",result);
        return result;
    }


    /**
     *  restful post 請求
     * @author liuao
     * @date 2018/7/19 11:13
     */
    public static Map doPost(String url, Map param){
        try {
            Client client = Client.create();
            URI u = new URI(url);
            WebResource resource = client.resource(u);
            MultivaluedMap<String, String> params = new MultivaluedMapImpl();

            Iterator i$ = param.entrySet().iterator();
            while(i$.hasNext()) {
                Map.Entry<String, List<String>> e = (Map.Entry)i$.next();
                params.add(e.getKey(),  String.valueOf(e.getValue()) );
            }

            logger.info("查詢引數:" + params.toString());
            String result = resource.type(MediaType.APPLICATION_FORM_URLENCODED).post(String.class, params);

            logger.info("url = :{},返回結果:{}", url, result);
            JSONObject jasonObject = JSONObject.parseObject(result);
            return  (Map)jasonObject;

        } catch (Exception e) {
            logger.error("..........",e );
        }
        return null;
    }

    /**
     *  post str
     * @author liuao
     * @date 2018/9/26 14:24
     */
    public static String postXML(String url, String xmlData) {
        logger.info(".....unifiedOrder.....請求引數..:{}", xmlData);
        OkHttpClient okHttpClient = new OkHttpClient();
        RequestBody body = RequestBody.create(XML, xmlData);
        Request request = new Request.Builder()
                .post(body)
                .url(url)
                .addHeader("Accept", "application/xml")
                .build();
        Call call = okHttpClient.newCall(request);
        try {
            Response response1 = call.execute();
            String result =  response1.body().string();

            logger.info("..postXML..返回結果....{}", result);
            return result;
        } catch (IOException e) {
            logger.error("..........",e );
        }

        return null;
    }



}

詳細細節可參考小程式二維碼生成API

補充:

想通過auto_color設定為false,line_color設定rgb來調一個自定義主色調二維碼,但是一直是黑色,後來仔細看了一下官方文件,上面有句話是“如果顏色依然是黑色,則說明不建議配置主色調”,不知道可有人遇見,在此備註一下。