restTemplate 使用

倾然丶 夕夏残阳落幕 提交于 2020-01-31 05:30:24


参考https://www.jianshu.com/p/27a82c494413,侵权删(仅学习后敲一遍)

restTemplate

简述RestTemplate

是Spring用于同步client端的核心类,简化了与http服务的通信,并满足RestFul原则,程序代码可以给它提供URL,并提取结果。默认情况下,RestTemplate默认依赖jdk的HTTP连接工具。当然你也可以 通过setRequestFactory属性切换到不同的HTTP源,比如Apache HttpComponents、Netty和OkHttp。

RestTemplate能大幅简化了提交表单数据的难度,并且附带了自动转换JSON数据的功能,但只有理解了HttpEntity的组成结构(header与body),且理解了与uriVariables之间的差异,才能真正掌握其用法。这一点在Post请求更加突出,下面会介绍到。

GET 请求实践

getForObject()方法

getForObject()其实比getForEntity()多包含了将HTTP转成POJO的功能,但是getForObject没有处理response的能力。因为它拿到手的就是成型的pojo。省略了很多response的信息。

public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables){}
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
public <T> T getForObject(URI url, Class<T> responseType)

带参数get请求

/**
 * get 请求 ,参数(占位符)传参
 */
@Test
public void testGet(){
    String api = "http://192.168.6.9:8060/ronghe/sendMessage/register?username={username}";
    User user = this.restTemplate.getForObject(api, User.class ,"13588888888");
    System.out.println(user);
}

/**
 * get 请求 ,用 map 传参
 */
@Test
public void testGet2(){
    String api = "http://192.168.6.9:8060/ronghe/sendMessage/register?username={username}";
    Map<String,String> map = new HashMap<>();
    map.put("username","13588888888");
    User user = this.restTemplate.getForObject(api, User.class ,map);
    System.out.println(user);
}

getForEntity()方法

public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables){}
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables){}
public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType){}

带参数的get请求

/**
     * getForEntity()方法 , 有返回值
     */
    @Test
    public void testGEtForEntity(){
        String api = "http://192.168.6.9:8060/ronghe/exBox/countFreeBox?cabinetNo={cabinetNo}&boxClassify={boxClassify}";
        Map<String,String> map = new HashMap<>();
        map.put("cabinetNo","99999999");
        map.put("boxClassify","2");
        ResponseEntity<BoxTypeDTO> responseEntity = restTemplate.getForEntity(api,BoxTypeDTO.class,map );
        BoxTypeDTO boxTypeDTO = responseEntity.getBody();
    }

POST 请求实践

也分为 postForEntitygetForObject 方法

postForEntity 方法

postForObject 方法形参一致

 public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException{}

    public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {}

    public <T> ResponseEntity<T> postForEntity(URI url, @Nullable Object request, Class<T> responseType) throws RestClientException {}

返回的是ResponseEntity对象,如果需要转换成pojo,还需要json工具类的引入,这个按个人喜好用。不会解析json的可以百度FastJson或者Jackson等工具类。然后我们就研究一下ResponseEntity下面有啥方法。

ResponseEntity、HttpStatus、BodyBuilder结构

ResponseEntity.java

public HttpStatus getStatusCode(){}
public int getStatusCodeValue(){}
public boolean equals(@Nullable Object other) {}
public String toString() {}
public static BodyBuilder status(HttpStatus status) {}
public static BodyBuilder ok() {}
public static <T> ResponseEntity<T> ok(T body) {}
public static BodyBuilder created(URI location) {}
...

HttpStatus.java

public enum HttpStatus {
public boolean is1xxInformational() {}
public boolean is2xxSuccessful() {}
public boolean is3xxRedirection() {}
public boolean is4xxClientError() {}
public boolean is5xxServerError() {}
public boolean isError() {}
}

BodyBuilder.java

public interface BodyBuilder extends HeadersBuilder<BodyBuilder> {
    //设置正文的长度,以字节为单位,由Content-Length标头
      BodyBuilder contentLength(long contentLength);
    //设置body的MediaType 类型
      BodyBuilder contentType(MediaType contentType);
    //设置响应实体的主体并返回它。
      <T> ResponseEntity<T> body(@Nullable T body);

可以看出来,ResponseEntity包含了HttpStatus和BodyBuilder的这些信息,这更方便我们处理response原生的东西。

post 方法带参数

@Test
public void test4(){
     String api = "http://192.168.6.9:8060/ronghe/exBox/countFreeBox";
     BoxCountDTO boxCountDTO = new BoxCountDTO();
     boxCountDTO.setBoxClassify("2");
     boxCountDTO.setCabinetNo("99999999");
     ResponseEntity<BoxTypeDTO> responseEntity = restTemplate.postForEntity(api , boxCountDTO, BoxTypeDTO.class);
     BoxTypeDTO body = responseEntity.getBody();
 }

get 方法带参数带请求头
我习惯用String.class 去接收返回值,然后通过Json 转换,获取对象。
个人不建议和别人对接接口的时候,直接用对象的形式去返回(因为之前项目的接口被人改了,也不知道自己去改)

@Test
    public void test4(){
        String api = "http://192.168.6.9:8060/ronghe/exBox/countFreeBox";
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); // 注意,自己测试的时候,需要把@RequestBody 注解去掉
        MultiValueMap<String, String> map= new LinkedMultiValueMap<>(); 
        map.add("cabinetNo", "99999999");
        map.add("boxClassify","3");
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
        ResponseEntity<String> response = restTemplate.postForEntity( api, request , String.class );
        String body = response.getBody();

也可以全局设置请求头,但是好似一个完美的解决方案,实质太局限性的操作了,我还是喜欢每个请求里写上,防止耦合…

未完待续。。。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!