应用场景:
- 实际应用场景:比如分享助力、名片分享之类的页面需要生成二维码
- 为满足不同需求和场景,小程序提供了三个接口,开发者可挑选适合自己的接口
- 接口A:适用于需要的码数量较少的业务场景
- 生成小程序码,可接受 path 参数较长,生成个数受限,数量限制见 下面注意事项,请谨慎使用。
- 接口B:适用于需要的码数量极多的业务场景
- 生成小程序码,可接受页面参数较短,生成个数不受限。
- 接口C:适用于需要的码数量较少的业务场景
- 生成二维码,可接受 path 参数较长,生成个数受限,数量限制见 注意事项。
注意事项:
- 接口只能生成已发布的小程序的二维码
- 接口 A 加上接口 C,总共生成的码数量限制为 100,000,请谨慎调用
- 接口 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;
}
}
补充:
想通过auto_color设置为false,line_color设置rgb来调一个自定义主色调二维码,但是一直是黑色,后来仔细看了一下官方文档,上面有句话是“如果颜色依然是黑色,则说明不建议配置主色调”,不知道可有人遇见,在此备注一下。