使用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();
        }
    }