微信扫描带参二维码推送事件(二)

    xiaoxiao2022-12-05  44

    上个帖子已经配置好了微信服务器,下面就是要调微信接口生成带参二维码 具体接口信息请参考微信官方文档:微信官方文档 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>

    下个帖子会讲扫码后的事件推送,也是第一次接触,不懂的大家可以多多交流。

    最新回复(0)