上个帖子已经配置好了微信服务器,下面就是要调微信接口生成带参二维码
具体接口信息请参考微信官方文档:微信官方文档
1、生成带参数的二维码
(1)、调微信接口生成生成二维码前先要获取 access_token,下面是获取access_token的方法。
public class Util {
// 微信获取accessToken接口
private static final String ACCESSTOKENURL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appId}&secret={appSecret}";
//appid
private static final String appid = " "; //这里是公众号后台的 appID
//appSecret
private static final String appSecret = " "; //这里是公众号后台的 appsecret
/**
* 获取access_Token
*
* @return
*/
public String getAccessToken() {
String url = ACCESSTOKENURL.replace("{appId}", appid).replace("{appSecret}", appSecret);
String accessTokenJsonStr = HttpRequest.get(url, null, false);
Map<String, String> accessTokenMap = GsonUtil.fromJson(accessTokenJsonStr, Map.class);
String accessToken = null;
if (null != accessTokenMap && !accessTokenMap.isEmpty()) {
accessToken = accessTokenMap.get("access_token");
if (!StringUtils.isEmpty(accessToken)) {
LogUtil.info("时间:" + DateUtil.getDateStr(new Date()) + ";成功获取accessToken;值为:" + accessToken);
}
}
if (StringUtils.isEmpty(accessToken)) {
String errCode = null;
String errMsg = null;
try {
errCode = accessTokenMap.get("errcode");
errMsg = accessTokenMap.get("errmsg");
} catch (Exception e) {
}
LogUtil.info("时间:" + DateUtil.getDateStr(new Date()) + ";获取accessToken失败;errCode为:" + errCode + ";errMsg" + errMsg);
}
return accessToken;
}
}
下面是封装的请求方法,网上很多仅供参考,代码可能会报错,需要导一些架包,这里就不写了,后面把pom文件发出来,根据需要进行导入 ,下面是代码:
package com.wechat.util;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
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.client.methods.HttpRequestBase;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.Map;
/**
* Created by rongyaowen
* on 2018/10/22.
*/
public class HttpRequest {
private static final String PROXY_HOST_NAME = "";
private static final int PROXY_PORT = 0;
private static final String PROXY_SCHEME = "http";
// 需要代理请改为true
private static final boolean OPEN_PROXY = false;
/**
* get请求
*
* @param url
* @param ignoreHttps 是否忽略https证书 true 忽略
* @return
*/
public static String get(String url, Map<String, String> header, boolean ignoreHttps) {
StringBuffer logSb = new StringBuffer();
logSb.append("[GET]-").append("url:[" + url + "]-").append("header:[");
// 创建httpGet请求,设置httpGet请求的头部信息
HttpGet httpGet = new HttpGet(url);
// 设置头信息
if (null != header && !header.isEmpty()) {
for (Map.Entry<String, String> entry : header.entrySet()) {
httpGet.addHeader(entry.getKey(), entry.getValue());
logSb.append(entry.getKey()).append(":").append(entry.getValue()).append(",");
}
}
logSb.append("]-");
logSb.append(ignoreHttps == true ? "[忽略https证书]-" : "[不忽略https证书]-");
logSb.append(OPEN_PROXY == true ? ("[开启代理" + PROXY_SCHEME + "://" + PROXY_HOST_NAME + ":" + PROXY_PORT + "]-") : "[未开启代理]");
LogUtil.info(logSb);
String resStr = response(httpGet, ignoreHttps);
LogUtil.info("响应报文:[" + resStr + "]");
return resStr;
}
/**
* post请求
*
* @param url
* @param param 请求体参数
* @param header 请求头
* @param cotentType 请求数据类型
* @param ignoreHttps 是否忽略https证书 true 忽略
* @return
*/
public static String post(String url, String param, Map<String, String> header, String cotentType, boolean ignoreHttps) {
StringBuffer logSb = new StringBuffer();
logSb.append("[GET]-").append("url:[" + url + "]-").append("param:[" + param + "]-").append("header:[");
HttpPost httpPost = new HttpPost(url);
// 设置请求数据
StringEntity stringEntity = new StringEntity(param, Charset.forName("UTF-8"));
stringEntity.setContentEncoding("UTF-8");
// 发送Json格式的数据请求
stringEntity.setContentType(cotentType);
httpPost.setEntity(stringEntity);
// 设置头信息
if (null != header && !header.isEmpty()) {
for (Map.Entry<String, String> entry : header.entrySet()) {
httpPost.addHeader(entry.getKey(), entry.getValue());
logSb.append(entry.getKey() + ":" + entry.getValue());
}
}
logSb.append("]-");
logSb.append("cotentType" + "[" + cotentType + "]-");
logSb.append(ignoreHttps == true ? "[忽略https证书]-" : "[不忽略https证书]-");
logSb.append(OPEN_PROXY == true ? ("[开启代理" + PROXY_SCHEME + "://" + PROXY_HOST_NAME + ":" + PROXY_PORT + "]-") : "[未开启代理]");
LogUtil.info(logSb);
String resStr = response(httpPost, ignoreHttps);
LogUtil.info("响应报文:[" + resStr + "]");
return resStr;
}
/**
* post请求获取流对象
*
* @param url
* @param param
* @param header
* @param cotentType
* @param ignoreHttps
* @return
*/
public static InputStream postAsStream(String url, String param, Map<String, String> header, String cotentType, boolean ignoreHttps) {
StringBuffer logSb = new StringBuffer();
logSb.append("[GET]-").append("url:[" + url + "]-").append("param:[" + param + "]-").append("header:[");
HttpPost httpPost = new HttpPost(url);
// 设置请求数据
StringEntity stringEntity = new StringEntity(param, Charset.forName("UTF-8"));
stringEntity.setContentEncoding("UTF-8");
// 发送Json格式的数据请求
stringEntity.setContentType(cotentType);
httpPost.setEntity(stringEntity);
// 设置头信息
if (null != header && !header.isEmpty()) {
for (Map.Entry<String, String> entry : header.entrySet()) {
httpPost.addHeader(entry.getKey(), entry.getValue());
logSb.append(entry.getKey() + ":" + entry.getValue());
}
}
logSb.append("]-");
logSb.append("cotentType" + "[" + cotentType + "]-");
logSb.append(ignoreHttps == true ? "[忽略https证书]-" : "[不忽略https证书]-");
logSb.append(OPEN_PROXY == true ? ("[开启代理" + PROXY_SCHEME + "://" + PROXY_HOST_NAME + ":" + PROXY_PORT + "]-") : "[未开启代理]");
LogUtil.info(logSb);
return responseAsStream(httpPost, ignoreHttps);
}
/**
* 获取请求数据
*
* @param httpRequestBase
* @param ignoreHttps
* @return
*/
private static InputStream responseAsStream(HttpRequestBase httpRequestBase, boolean ignoreHttps) {
CloseableHttpClient closeableHttpClient;
if (ignoreHttps) {
closeableHttpClient = getIgnoreHttpsClient();
} else {
closeableHttpClient = getClient();
}
CloseableHttpResponse closeableHttpResponse = null;
String res = null;
InputStream inputStream = null;
try {
closeableHttpResponse = closeableHttpClient.execute(httpRequestBase);
if (closeableHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = closeableHttpResponse.getEntity();
inputStream = entity.getContent();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != closeableHttpResponse) {
closeableHttpResponse.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return inputStream;
}
/**
* 获取请求数据
*
* @param httpRequestBase
* @param ignoreHttps
* @return
*/
private static String response(HttpRequestBase httpRequestBase, boolean ignoreHttps) {
CloseableHttpClient closeableHttpClient;
if (ignoreHttps) {
closeableHttpClient = getIgnoreHttpsClient();
} else {
closeableHttpClient = getClient();
}
CloseableHttpResponse closeableHttpResponse = null;
String res = null;
try {
closeableHttpResponse = closeableHttpClient.execute(httpRequestBase);
if (closeableHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = closeableHttpResponse.getEntity();
res = EntityUtils.toString(entity, "utf-8");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != closeableHttpResponse) {
closeableHttpResponse.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return res;
}
/**
* @return
*/
private static RequestConfig getRequestConfig() {
// 依次是代理地址,代理端口号,协议类型
HttpHost proxy = new HttpHost(PROXY_HOST_NAME, PROXY_PORT, PROXY_SCHEME);
if (OPEN_PROXY) {
return RequestConfig.custom().setProxy(proxy).setConnectionRequestTimeout(20000).setConnectTimeout(20000).setSocketTimeout(20000).build();
} else {
return RequestConfig.custom().setConnectionRequestTimeout(20000).setConnectTimeout(20000).setSocketTimeout(20000).build();
}
}
/**
* 获取忽略https的client
*
* @return
* @throws Exception
*/
private static CloseableHttpClient getIgnoreHttpsClient() {
SSLContext sslContext = null;
try {
sslContext = SSLContexts.custom().useTLS().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType) {
//信任所有
return true;
}
}).build();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new AllowAllHostnameVerifier());
Registry<ConnectionSocketFactory> r = RegistryBuilder.<ConnectionSocketFactory>create().register("https", sslConnectionSocketFactory).build();
//设置连接池,配置过期时间为20s。
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(r);
cm.setMaxTotal(500);
cm.setDefaultMaxPerRoute(350);
SocketConfig socketConfig = SocketConfig.custom().setSoKeepAlive(true).setTcpNoDelay(true).setSoTimeout(20000).build();
cm.setDefaultSocketConfig(socketConfig);
RequestConfig requestConfig = getRequestConfig();
//创建httpClient
CloseableHttpClient closeableHttpClient = HttpClientBuilder.create().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).build();
return closeableHttpClient;
}
/**
* 获取httpclient
*
* @return
*/
private static CloseableHttpClient getClient() {
//设置连接池,配置过期时间为20s。
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(500);
cm.setDefaultMaxPerRoute(350);
SocketConfig socketConfig = SocketConfig.custom().setSoKeepAlive(true).setTcpNoDelay(true).setSoTimeout(20000).build();
cm.setDefaultSocketConfig(socketConfig);
RequestConfig requestConfig = getRequestConfig();
//创建httpClient
CloseableHttpClient closeableHttpClient = HttpClientBuilder.create().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).build();
return closeableHttpClient;
}
}
2、access_token 已经获取到了,下面就可以调接口获取二维码了
生成的二维码可以根据自己的需求进行生成,这里生成是永久的二维码的,两种入参格式。可以参考下微信的文档:公众号官方文档
创建字符串形式的二维码参数:
{"action_name": "QR_LIMIT_STR_SCENE", "action_info": {"scene": {"scene_str": "test"}}}
创建整型参数值形式的二维码参数:
{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 123}}}
二维码类型,QR_SCENE为临时的整型参数值,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久的整型参数值,QR_LIMIT_STR_SCENE为永久的字符串参数值
接下来返回的是可以直接显示二维码的url:
// 获取ticket
private static final String GET_QRCODE_URL = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={TOKEN}";
// 换取二维码
private static final String QR_CODE_URL = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={TICKET}";
public String getYJQrCode() {
//获取access_token
String access_token=util.getAccessToken();
JSONObject req=new JSONObject();
JSONObject data=new JSONObject();
JSONObject datare=new JSONObject();
req.put("action_name","QR_LIMIT_STR_SCENE");
datare.put("scene_str","000165");
data.put("scene",datare);
req.put("action_info",data);
System.out.println("获取二维码入参"+req);
String url = GET_QRCODE_URL.replace("{TOKEN}", access_token);
JSONObject res= HttpClientUtil.doPost(req,url);
System.out.println("获取二维码出参"+res);
String ticket=res.optString("ticket");
String returnUrl = QR_CODE_URL.replace("{TICKET}", ticket);
return returnUrl;
}
把pom文件导出来可以根据需要添加架包:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wry</groupId>
<artifactId>wechat</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient-cache</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.10</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.1.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
下个帖子会讲扫码后的事件推送,也是第一次接触,不懂的大家可以多多交流。