查遍全网资料都没有找到自己想要的 - - 偷懒不成自己研究,在经历无数个小坑后,终于搞定!发布出来为新同学节省宝贵开发时间,哈哈。话不多说直接上代码!(欢迎留言交流,并点赞,啊哈!)
一、实体类
package com.wx.mp.api.response;
import lombok.Getter;
import lombok.Setter;
/**
* 小程序码实体类--获取小程序码,适用于需要的码数量极多的业务场景。通过该接口生成的小程序码,永久有效,数量暂无限制。
*
* @author yyh
*/
@Getter
@Setter
public class WxCodeUnlimitedResponse {
private static final long serialVersionUID = -4984614130194041909L;
/**
* 请求失败错误码
*/
private String errcode;
/**
* 请求失败错误信息
*/
private String errmsg;
/**
* 图片信息
*/
private byte[] buffer;
}
二、接口
package com.wx.mp.api.service;
import java.util.Map;
import com.wx.mp.api.response.WxCodeUnlimitedResponse;
/**
* 微信小程序相关--小程序码--接口
*
* @author yyh
*/
public interface IWxacodeService {
/**
* 获取小程序码,适用于需要的码数量极多的业务场景。通过该接口生成的小程序码,永久有效,数量暂无限制
*
* @param access_token --必填:是-- 接口调用凭证
* @param scene --必填:是--
* 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,
* 其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
* @param page --必填:是-- 必须是已经发布的小程序存在的页面(否则报错),例如 pages/index/index,
* 根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面
* @param width --必填:是-- 二维码的宽度,单位 px。最小 280px,最大 1280px
* @param auto_color --必填:是-- 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调
* @param line_color --必填:是-- auto_color 为 false 时生效,使用 rgb 设置颜色 例如
* {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示
* @param is_hyaline --必填:是-- 是否需要透明底色,为 true 时,生成透明底色的小程序码
* @param imagePath --必填:否-- 图片物理路径,当传入此值后会在相应路径生成小程序码
* @return
*/
public WxCodeUnlimitedResponse getUnlimited(String access_token, String scene, String page, Integer width,
boolean auto_color, Map line_color, boolean is_hyaline, String imagePath);
}
三、实现类
package com.wx.mp.api.service.impl;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
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.protocol.HTTP;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.alibaba.fastjson.JSON;
import com.wx.mp.api.response.WxCodeUnlimitedResponse;
import com.wx.mp.api.service.IWxacodeService;
import net.sf.json.JSONObject;
/**
* 微信小程序相关授权--小程序码--接口实现类
*
* @author yyh
*/
@Service
public class WxacodeServiceImpl implements IWxacodeService {
private static final Logger LOGGER = LoggerFactory.getLogger(WxacodeServiceImpl.class);
// rest服务
private RestTemplate restTemplate = new RestTemplate();
/**
* 获取小程序码,适用于需要的码数量极多的业务场景。通过该接口生成的小程序码,永久有效,数量暂无限制
*
* @param access_token --必填:是-- 接口调用凭证
* @param scene --必填:是--
* 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,
* 其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
* @param page --必填:否-- 必须是已经发布的小程序存在的页面(否则报错),例如 pages/index/index,
* 根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面
* @param width --必填:否-- 二维码的宽度,单位 px。最小 280px,最大 1280px。默认430px
* @param auto_color --必填:否-- 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调
* @param line_color --必填:否-- auto_color 为 false 时生效,使用 rgb 设置颜色 例如
* {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示
* @param is_hyaline --必填:否-- 是否需要透明底色,为 true 时,生成透明底色的小程序码
* @param imagePath --必填:否--
* 图片物理路径,当传入此值后(如:"D:\\upload\\xcx.png")会在相应路径生成小程序码
* @return
*/
public WxCodeUnlimitedResponse getUnlimited(String access_token, String scene, String page, Integer width,
boolean auto_color, Map line_color, boolean is_hyaline, String imagePath) {
WxCodeUnlimitedResponse res = new WxCodeUnlimitedResponse();
// url请求参数值
Map params = new HashMap();
// params.put("access_token", access_token);//**注意:将access_token参数放到url中,否则请求会失败
params.put("scene", scene);
params.put("auto_color", auto_color);
params.put("is_hyaline", is_hyaline);
if (StringUtils.isNotBlank(page)) {
params.put("page", page);
}
if (null != width) {
params.put("width", width);
}
if (null != line_color) {
params.put("line_color", line_color);
}
byte[] byteArray = null;
/** 第一种方式:使用RestTemplate。项目采用了这种方式。 **/
/** start **/
// 调用微信接口
try {
ResponseEntity entity = restTemplate.postForEntity(
"https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + access_token,
JSON.toJSONString(params), byte[].class);
// 如果你十分确认微信正确返回了图片,那么byteArray已经是你想要的结果了。
byteArray = entity.getBody();// 图片或错误信息
String wxReturnStr = new String(byteArray);// 微信返回内容,byte[]转为string
if (wxReturnStr.indexOf("errcode") != -1) {
JSONObject json = JSONObject.fromObject(wxReturnStr);
res.setErrcode(json.get("errcode").toString());
res.setErrmsg(json.get("errmsg").toString());
} else {
res.setErrcode("0");
res.setErrmsg("ok");
res.setBuffer(byteArray);
}
} catch (Exception e) {
LOGGER.error("微信小程序码getUnlimited接口调用失败", e);
}
/** end **/
/** 第二种方式:使用HttpPost请求。因项目中采用了第一种方式,故此方法只测试了图片信息的成功返回,没有处理错误信息的返回。 **/
/** start **/
/*
HttpResponse response = null;
// 设置请求
HttpPost httpPost = new HttpPost(
"https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + access_token);
httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
try {
StringEntity entity = new StringEntity(JSON.toJSONString(params));
entity.setContentType("image/png");
httpPost.setEntity(entity);
} catch (UnsupportedEncodingException e) {
LOGGER.error("本地参数转码失败--调用微信小程序码getUnlimited接口失败", e);
}
// 发送请求
try {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
response = httpClient.execute(httpPost);
} catch (Exception e) {
LOGGER.error("微信小程序码getUnlimited接口调用失败", e);
}
// 读取微信返回的小程序码
try {
InputStream inputStream = response.getEntity().getContent();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int bytesRead = 0;
while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
outStream.flush();
outStream.close();
byteArray = outStream.toByteArray();
} catch (Exception e) {
LOGGER.error("本地读取微信小程序码失败", e);
}
*/
/** end **/
/**将小程序码保存到本地**/
this.generateLocalPic(imagePath, byteArray);
return res;
}
/** 将小程序码保存到本地 **/
private void generateLocalPic(String imagePath, byte[] byteArray) {
if (StringUtils.isNotBlank(imagePath) && null != byteArray) {
try {
File file = new File(imagePath);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
FileOutputStream out = new FileOutputStream(imagePath);
out.write(byteArray);
out.flush();
out.close();
} catch (Exception e) {
LOGGER.error("本地存储微信小程序码失败", e);
}
}
}
}