使用spring boot时想调用微信的接口生成小程序码,传统的做法都是自己发送http请求,然后中间要处理各种情况,非常的麻烦。现在我们可以很容易的在spring boot中集成spring cloud的feign进行远程调用。
1.生成微信小程序码的两个步骤
如何获取微信小程序码,可以参照官方 微信小程序文档。主要分为两个步骤:
- 1.通过appid和appsecret获取AccessToken
- 2.调用微信接口获取小程序码,这一步需要上面获取的accessToken
2.spring boot中集成feign
2.1引入feign依赖
引入openfeign依赖,官方的另一个依赖叫“spring-cloud-starter-feign”已经被弃用,这里要注意一下。openfeign的版本与spring boot的版本相匹配
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>{spring boot version}</version>
</dependency>
在spring boot的主启动类上面加上@EnableFeignClient
注解
2.2创建feign接口
这里有几个坑需要注意,这也是我想写这篇文章的主要原因…
- 1.@FeignClient的name和url属性一定不能少
- 2.必须是@RequestMapping而不能是RESTFul的@GetMapping或者其他
- 3.@RequestParam的name属性一定不能少
- 4.在接收微信返回给我们的数据时,官方文档上说返回的是
Buffer
对应的java返回值就是byte数组
@FeignClient(name = "wechat", url = "https://api.weixin.qq.com")
public interface WxQrCodeFeignService {
/**
* 获取微信授权token
* @param appid
* @param secret
* @return
*/
@RequestMapping(value = "/cgi-bin/token?grant_type=client_credential", method = RequestMethod.GET)
String getAccessToken(@RequestParam(name = "appid") String appid, @RequestParam(name = "secret") String secret);
/**
* 生成无限制的小程序码
* @param accessToken
* @param cmd
* @return
*/
@RequestMapping(value = "/wxa/getwxacodeunlimit?access_token={accessToken}", method = RequestMethod.POST, consumes = "application/json")
byte[] getUnlimited(@PathVariable("accessToken") String accessToken, WxQrTokenCmd cmd);
}
2.3 调用feign接口
微信比较坑的一点是,在调用获取小程序的时候,accessToken是在url中传递,其他参数是以json形式post提交的。要是没有注意这一点,能调试到让你怀疑人生。
//以bean的方式注入上面的feign接口
@Autowired
private WxQrCodeFeignService wxqrCodeFeignService;
//1获取token
String res = wxqrCodeFeignService.getAccessToken(APPID, APPSECRET);
//2.获取小程序码
WxQrTokenCmd cmd = new WxQrTokenCmd(deliveryPlaceId, "pages/index/index");
byte[] buffer = wxqrCodeFeignService.getUnlimited(wxQrToken.getAccessToken(), cmd);
return "data:image/png;base64," + new String(Base64.encodeBase64(buffer));
WxQrTokenCmd是根据自己业务进行封装的一个类
public class WxQrTokenCmd {
private String scene;
private String page;
}
三行代码搞定http远程调用,是不是很爽。呐,下面这是使用传统的httpclient调用的代码,你想选哪个呢?
代码来自 非常感谢这个博主关于如何生成小程序码步骤的讲解。
public static void main(String[] args){
try{
URL url = new URL("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=你的access_token");
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", "a=1234567890");
paramJson.put("page", "pages/index/index");
paramJson.put("width", 430);
paramJson.put("auto_color", true);
printWriter.write(paramJson.toString());
// flush输出流的缓冲
printWriter.flush();
//开始获取数据
BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream());
OutputStream os = new FileOutputStream(new File("/Users/Xxxx/Music/abc.png"));
int len;
byte[] arr = new byte[1024];
while ((len = bis.read(arr)) != -1)
{
os.write(arr, 0, len);
os.flush();
}
os.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}