RestTemplate的使用

259 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情

RestTemplate

\qquadRestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。其实想到接触RestTemplate还是女票提了一个需求,就是前一段时间很火的公众号推送,随便在小红书上截个图,顺分析一波内容的构成以及怎么获取,顺便讲一下RestTemplate的基本使用。 image.png \qquad这里面时间相关的API就不讲了,因为实现的方式也比较简单,主要讲一下天气API的调用,以及微信模板消息接口的请求,这两个分别对应GET和POST请求。

1. GET请求

\qquadRestTemplate提供了两类发送GET请求的方式getForObject()和getForEntity(),这两种方法分别有自己的重载。两个方法的主要区别在于前者直接获取响应内容,后者则获取的响应信息,包含响应状态、响应头和响应内容。

@Override
@Nullable
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) 
@Override
@Nullable
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) 
@Override
@Nullable
public <T> T getForObject(URI url, Class<T> responseType) 
@Override
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
@Override
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
@Override
public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType)

这里只复制了方法和参数,没有复制抛出的异常和具体实现,主要了解的是各个参数的含义:
\qquadString url:请求的路径,可以是带参数可以不带参数。
\qquadClass responseTyp:响应的类型,也就是响应内容要映射实体类。
\qquadObject... uriVariables:这是一个可变参数,当请求路径上带有参数时可以使用这种方式进行传参。假如请求的路径是这样的http://www.localhost.com/list/{1}/{2},可以直接将{1}和{2}这里要填的值直接凭借上去,作为整体的url传递给方法,你也可以用可变参数进行传递,注意顺序。

//Result.class代表结果类
Result result = restTemplate.getForObject("http://fantj.top/notice/list/1/5", Result.class);
    
Result result = restTemplate.getForObject("http://fantj.top/notice/list/{1}/{2}", Result.class,1,5);

\qquadMap<String, ?>:也是在有参数的时候进行使用,默认解析的是PathVariable的url形式,跟上面的效果一样

Map<String,String> map = new HashMap(); 
map.put("start","1"); 
map.put("page","5"); 
Notice notice = restTemplate.getForObject("http://fantj.top/notice/list/" , Notice.class,map);

\qquad如果是RequestParam这样的则是需要直接进行拼接,作为url传递给方法。比如这个天气接口,用的是和风天气的API,这里需要注意的是,它的返回值是经过压缩的,用PostMan请求看起来是正常的,但是直接接受就会报错,需要用字节数组来接受处理后,在获取想要的内容。

public JsonRootBean restTemplateGetTest() throws IOException {
    RestTemplate restTemplate = new RestTemplate();
    
    //Constants.WEATHER是url,它的值是
'https://api.qweather.com/v7/weather/3d?location=101010100&key=YOUR_KEY'

    ResponseEntity<byte[]> bytes = restTemplate.getForEntity(Constants.WEATHER, byte[].class);
    byte[] content = bytes.getBody();
    String s = ZipUtils.getSource(content);
    ObjectMapper objectMapper = new ObjectMapper();
    JsonRootBean jsonRootBean1 = objectMapper.readValue(s,JsonRootBean.class);
    return jsonRootBean1;
}

2. POST请求

\qquadPOST请求常用的也是postForObject和postForEntity,区别就不说了,这里还是需要注意方法参数的含义

//url:请求路径
//request:POST请求需要的参数,一般是Json格式的字符串,但是我建议封装成一个HttpEntity发送
//responseType:响应内容要映射的类型
//uriVariables:路径上的参数
public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request,
      Class<T> responseType, Object... uriVariables)

\qquad举个例子,代码如下,对微信模板消息接口进行请求,如果没有封装响应体,直接将要传递的参数转成Json格式的字符串进行传递,则接受到的消息很可能是乱码(我试的时候是这样)。然后,同HttpHeaders设置请求头,主要是规范内容的格式,然后用传递的实体类和httpHeaders构建出一个请求体,传递给postForEntity方法,这样避免出现乱码问题,得到的响应信息用来判断是否请求成功。这里的接口是 https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=ACCESS_TOKEN,ACCESS_TOKEN也是由微信提供的接口获取的。

public void rtPostObject(String token,WeChatSebdBody weChatSebdBody) throws JsonProcessingException {

    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.add("Content-Type", "application/json;charset=utf-8");
    HttpEntity<WeChatSebdBody> entity = new HttpEntity<>(weChatSebdBody,httpHeaders);

    RestTemplate restTemplate = new RestTemplate();
    String url = Constants.WEIXIN_PATH+Constants.WeChatSend+token;

    ResponseEntity<String> response = restTemplate.postForEntity(url,entity,String.class);

}

\qquad顺带一提,和风天气的使用需要创建一个项目,用key作为Token去获取数据。在微信的测试公众号里,用微信登录之后,就会产生appId和secret,ACCESS_TOKEN就使用这两个参数来获取的,因为大部分接口都需要用到ACCESS_TOKEN。得到这些数据后,封装好传递给消息模板接口,就可以进行展示,当然,展示的样式需要自己调整,结合定时任务就可以实现每天的定时推送。