1.实现微信小程序的菊花二维码接口首先第一步是需要去对接一个auth.getAccessToken接口
GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
因为此接口就是正常返回json数据的接口,这里我们就不写原生的http代码,我用了hutool的工具包
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.7</version>
</dependency>
接口实现的具体代码:
1.参数dto类
package com.sun.module.http.dto;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@Data
@ApiModel(value = "WeiXinAccessTokenDTO", description = "微信小程序http对接参数(auth.getAccessToken)")
public class WeiXinAccessTokenDTO {
private String grant_type;
private String appid;
private String secret;
}
2.控制层controller类
public Map<String, Object> getWeiXinAccessToken(@RequestBody WeiXinAccessTokenDTO dto) {
Map<String, Object> params = new HashMap<>();
params.put("grant_type", dto.getGrant_type());
params.put("appid", dto.getAppid());
params.put("secret", dto.getSecret());
String resultStr = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token", params);
String[] strings = resultStr.split(",");
String[] access_token = strings[0].split(":");
Map<String, Object> map = new HashMap<>();
map.put(access_token[0], access_token[1]);
//包含access_token的map
return map;
}
到这一步,就拿到了token,因为调用生成菊花二维码的接口必填参数就是token,
每个token有2个小时的有效时间,所以可以拿到后本地缓存起来一下
2.通过传入token,利用代码访问接口生成菊花二维码,并返回给前端
POST https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN
这里需要maven依赖
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.67</version>
</dependency>
1.参数dto类
@Data
@ApiModel(value = "WeiXinUnlimitedDTO", description = "微信小程序http对接参数(wxacode.getUnlimited)")
public class WeiXinUnlimitedDTO {
private String access_token;
//访问接口需要的选填的参数,直接map键值对转换json
private Map<String, Object> params;
}
2.服务层service类
这里可以选择是下载本地或者返回web选择性下载,具体参详注释内容
package com.sun.module.http;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
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.HttpClients;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
@Service
@Slf4j
public class HttpService {
/**
* 发送http请求访问微信小程序接口获得输入流
* @param URL
* @param json
* @return
*/
public static ByteArrayInputStream sendPost(String URL, String json) {
InputStream inputStream = null;
ByteArrayInputStream byteArrayInputStream = null;
// 创建默认的httpClient实例.
CloseableHttpClient httpclient = HttpClients.createDefault();
// 创建httppost
HttpPost httppost = new HttpPost(URL);
httppost.addHeader("Content-type", "application/json; charset=utf-8");
httppost.setHeader("Accept", "application/json");
try {
StringEntity s = new StringEntity(json, Charset.forName("UTF-8"));
s.setContentEncoding("UTF-8");
httppost.setEntity(s);
HttpResponse response = httpclient.execute(httppost);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
// 获取相应实体
HttpEntity entity = response.getEntity();
inputStream = entity.getContent();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
// 创建一个Buffer字符串
byte[] buffer = new byte[1024];
// 每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
// 使用一个输入流从buffer里把数据读取出来
while ((len = inputStream.read(buffer)) != -1) {
// 用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
// 关闭输入流
inputStream.close();
// 把outStream里的数据写入内存
byteArrayInputStream = new ByteArrayInputStream(outStream.toByteArray());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭连接,释放资源
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return byteArrayInputStream;
}
/**
* 返回菊花二维码图片给前端
* @param access_token
* @param paramJson
* @param response
* @return
*/
public Map<String, Object> getWXCode(String access_token, String paramJson, HttpServletResponse response) {
Map<String, Object> map = new HashMap<>();
try {
log.info("access_token:[{}]", access_token);
String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + access_token;
ByteArrayInputStream inputStream = sendPost(url, paramJson);
//这里判断的是返回的图片还是错误信息,一般错误信息不会大于200
if (inputStream.available() <= 200) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int i;
byte[] buffer = new byte[200];
while ((i = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, i);
}
String str = new String(byteArrayOutputStream.toByteArray());
//错误信息的格式在官方文档里有
JSONObject jsonObject = JSONObject.parseObject(str);
if ("41030".equals(jsonObject.getString("errcode"))) {
map.put("aa", "所传page页面不存在,或者小程序没有发布");
} else if ("45009".equals(jsonObject.getString("errcode"))) {
map.put("bb", "调用分钟频率受限");
}
byteArrayOutputStream.close();
return map;
}
//返回web前端
response.setContentType("image/png");
BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
byte[] buff = new byte[1024];
int n;
while ((n = inputStream.read(buff)) != -1) {
outputStream.write(buff, 0, n);
}
outputStream.flush();
outputStream.close();
inputStream.close();
//下载到本地的代码
// FileOutputStream fileOutputStream = new FileOutputStream("D:/123.png");
// int i;
// byte[] buffer = new byte[200];
// while ((i = inputStream.read(buffer)) != -1) {
// fileOutputStream.write(buffer, 0, i);
// }
// fileOutputStream.flush();
// fileOutputStream.close();
// inputStream.close();
map.put("trun", "菊花码生成成功");
} catch (Exception e) {
map.put("flase", "获取菊花码异常");
}
return map;
}
}
3.控制层controller类
public Map<String, Object> getWeiXinUnlimited(@RequestBody WeiXinUnlimitedDTO dto, HttpServletResponse response) {
Gson gson = new Gson();
String paramJson = gson.toJson(dto.getParams());
Map<String, Object> map = service.getWXCode(dto.getAccess_token(), paramJson, response);
return map;
}
最后在提一嘴,我所使用的jdk是1.8 ,spring parent如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>