RestTemplate

1、简介

  • RestTemplate是由Spring框架提供的一个可用于应用中调用rest服务的类它简化了与http服务的通信方式,统一了RESTFul的标准,封装了http连接,我们只需要传入url及其返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更为优雅的调用RESTFul服务的方式。
  • 在Spring应用程序中访问第三方REST服务与使用Spring RestTemplate类有关。RestTemplate类的设计原则与许多其他Spring的模板类(例如JdbcTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。
  • RestTemplate默认依赖JDK提供了http连接的能力(HttpURLConnection),如果有需要的话也可以通过setRequestFactory方法替换为例如Apache HttpCompoent、Netty或OKHttp等其他Http libaray。
  • 考虑到了RestTemplate类是为了调用REST服务而设计的,因此它的主要方法与REST的基础紧密相连就不足为奇了,后者时HTTP协议的方法:HEAD、GET、POST、PUT、DELETE、OPTIONS例如,RestTemplate类具有headForHeaders()、getForObject()、putForObject(),put()和delete()等方法。
     
  • delete() 在特定的URL上对资源执行HTTP DELETE操作
  • exchange() 在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中 映射得到的
  • execute() 在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象
  • getForEntity() 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象
  • getForObject() 发送一个HTTP GET请求,返回的请求体将映射为一个对象
  • postForEntity() POST 数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得到的
  • postForObject() POST 数据到一个URL,返回根据响应体匹配形成的对象
  • headForHeaders() 发送HTTP HEAD请求,返回包含特定资源URL的HTTP头
  • optionsForAllow() 发送HTTP OPTIONS请求,返回对特定URL的Allow头信息
  • postForLocation() POST 数据到一个URL,返回新创建资源的URL
  • put() PUT 资源到特定的URL

2、创建RestTemplate 

​        因为RestTemplate是Spirng框架提供的所以只要是一个Springboot项目就不用考虑导包的问题,这些都是提供好的。但是Spring并没有将其加入SpringBean容器中,需要我们手动加入,因为我们首先创建一个Springboot配置类,再在配置类中将我们的RestTemlate注册到Bean容器中

  • 自定义一些连接参数

使用Springboot提供的RestTemplateBuilder构造类来构造一个RestTemplate,可以自定义一些连接参数,如:连接超时时间,读取超时时间,还有认证信息等

@Configuration
public class WebConfiguration {
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder){
        return builder
                //设置连接超时时间
                .setConnectTimeout(Duration.ofSeconds(5000))
                //设置读取超时时间
                .setReadTimeout(Duration.ofSeconds(5000))
                //设置认证信息
                .basicAuthentication("username","password")
                //设置根路径
                .rootUri("https://api.test.com/")
                //构建
                .build();
    }
}
  • 自定义拦截器
@Slf4j
public class CustomClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        //打印请求明细
        logRequestDetails(request,body);
        ClientHttpResponse response = execution.execute(request, body);
        //打印响应明细
        logResponseDetails(response);
        return response;
    }

    private void logRequestDetails(HttpRequest request, byte[] body){
        log.debug("Headers:{}",request.getHeaders());
        log.debug("body:{}",new String(body, StandardCharsets.UTF_8));
        log.debug("{}:{}",request.getMethod(),request.getMethodValue());
    }

    private void logResponseDetails(ClientHttpResponse response) throws IOException {
        log.debug("Status code : {}",response.getStatusCode());
        log.debug("Status text : {}",response.getStatusText());
        log.debug("Headers : {}",response.getHeaders());
        log.debug("Response body: {}", StreamUtils.copyToString(response.getBody(),StandardCharsets.UTF_8));
    }
}
@Configuration
public class WebConfiguration {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder){
        return builder
                .additionalInterceptors(new CustomClientHttpRequestInterceptor())
                //构建
                .build();
    }    
}

3、RestTemplate API使用

3.1、GET

public <T> T getForObject(...)
public <T> ResponseEntity<T> getForEntity(...)
  • getForEntity()

getForEntity()方法

第一个参数为我要调用服务的URL

第二个参数则为响应内容的类的类型,还可以添加第三个参数,

第三个参数为一个可变参数 代表着调用服务时的传参,第三个参数可以使用key-value的map来传入参数

public void queryGet() {
    ResponseEntity<Object> responseEntity = restTemplate.getForEntity(
"https://com.test.api/v3?city=510100&key=222", Object.class);
    // 获取状态对象
    HttpStatus httpStatus = responseEntity.getStatusCode();
    // 获取状态码
    int statusCodeValue = responseEntity.getStatusCodeValue();
    // 获取headers
    HttpHeaders httpHeaders = responseEntity.getHeaders();
    // 获取body
    TempUser result = responseEntity.getBody();
}
  • getForObject()

相比于前者getForEntity()该方法则是,更偏向于直接获取响应内容的,因为他直接返回响应实体的body(响应内容)

public void queryGet() {
        JSONObject body = restTemplate.getForObject(
"https://www.test.com/v3?city=510100&key=111", JSONObject.class);
        System.out.println(body);
}

3.2、POST

public URI postForLocation(...)
public <T> T postForObject(...)
public <T> ResponseEntity<T> postForEntity(...)
  • postForEntity()

 该方法有三个参数,

 第一个为调用服务的地址(URL)

​ 第二个参数表示上传的参数(json格式提交)

​ 第三个表示返回响应内容的具体类型

​ 第四个参数也用于指定参数(在URL中添加)

@Override
public void queryPost() {
	JSONObject json = new JSONObject();
    json.put("aaa","111");
	ResponseEntity<Object> responseEntity = restTemplate.postForEntity(
"https://www.test.com/v3?city=510100", json, Object.class);
    System.out.println("消息响应内容:"+responseEntity.getBody());
    // 获取状态对象
    HttpStatus httpStatus = responseEntity.getStatusCode();
    // 获取状态码
    int statusCodeValue = responseEntity.getStatusCodeValue();
    // 获取headers
    HttpHeaders httpHeaders = responseEntity.getHeaders();
    // 获取body
    TempUser result = responseEntity.getBody();
}
  • postForObject()
public void queryPost() {
    JSONObject json = new JSONObject();
    json.put("aaa","111");
	JSONObject result = restTemplate.postForObject(
"https://www.test.com/post", json, JSONObject.class);
	System.out.println("消息响应内容:"+result);
}
  • postForLocation()

postForLocation传参用法与前两者一致,只不过返回从实体变成了一个URL,因此它不需要指定返回响应内容的类型。

public void queryPost() {
	JSONObject json = new JSONObject();
    json.put("aaa","111");
	URI uri = restTemplate.postForLocation(
"https://www.test.com/post", json);
	System.out.println(uri);
}

 这个只需要服务提供者返回一个 URI 即可,该URI返回值体现的是:用于提交完成数据之后的页面跳转,或数据提交完成之后的下一步数据操作URI

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值