您的位置:

RestTemplate是什么?

在微服务架构模式中,多个小型服务可以协同工作以提供一个特定的业务功能。这些服务之间可以通过REST API进行通信。要使用REST API,我们需要HTTP客户端,例如RestTemplate。RestTemplate是Spring框架提供的一个珍贵的HTTP客户端。它使开发人员能够使用HTTP请求进行远程调用。

一、RestTemplate的概述

RestTemplate是在Spring框架中提供的一个用于访问Rest服务的模板工具集,其实就是对HttpClient的封装。它提供了对HTTP请求生命周期的封装,使得开发者能够更方便地通过HTTP请求来调用Rest服务。

要使用RestTemplate,我们需要在Spring应用程序上下文中定义RestTemplate bean。可以使用如下语句快速创建RestTemplate:


RestTemplate restTemplate = new RestTemplate();

Spring提供了多种实现方式,包括Apache HttpClient以及Java原生URLConnection。它可以处理GET、POST、PUT、DELETE和其他HTTP请求方法,并且可以将服务端返回的JSON、XML和其他格式的数据进行转换。

二、实现RestTemplate基本使用

下面我们演示如何使用RestTemplate的GET请求方法。RestTemplate的getForObject()方法是RESTful API最好的工具。通过简单的代码行,我们就能够获取以JSON、XML等格式的数据。


RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/student/get/{id}";
Map<String, String> uriParams = new HashMap<>();
uriParams.put("id", "1");
Student student = restTemplate.getForObject(url, Student.class, uriParams);
System.out.println(student);

以上代码中使用了getForObject方法,其中参数说明如下:

  • url:目标URL,支持占位符URI。占位符以“{”和“}”包装,并且必须与url变量Map uriVariables和var-args参数(如果有)的键匹配。
  • responseType:返回类型,其可以是一个正常的对象类型,例如Student,或将响应映射到集合类型,例如List<Student>
  • uriVariables:占位符替换数组

除了GET请求方法,在RestTemplate中还有POST、PUT等常见的HTTP请求方法。这里就不详细展开了。

三、扩展RestTemplate的使用

1. 添加HTTP头信息

在发送HTTP请求时添加HTTP头信息,可以通过RestTemplate的Header请求头来实现:


RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);

ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);

在以上示例中,我们将添加accept Http头来请求响应。在类HttpHeaders的实例化中,设置accept值为MediaType.APPLICATION_JSON,表示在响应中请求JSON数据。

2. 错误处理

在远程服务调用时,总会存在网络连接失败等异常情况,我们需要捕获这些异常,并对其进行处理。

RestTemplate提供了一个特殊的类RestClientException,用于捕获所有的异常。例如,我们可以通过以下方式在RestTemplate调用失败时捕获异常:


try {
    ResponseEntity<String> response = restTemplate.getForEntity(URL, String.class);
} catch (RestClientException e) {
    e.printStackTrace();
}

3. 异步调用RestTemplate

RestTemplate的请求是同步的,但是在高并发场景下,使用异步方式调用可以提高系统的性能。

Java8之前使用Callable和Future,Java8之后可以使用CompletableFuture。下面是Java8之前的代码:


RestTemplate restTemplate = new RestTemplate();
String url = "localhost:8080/index";

Callable<Map> task = () -> {
    ResponseEntity<Map> exchange = restTemplate.exchange(url, HttpMethod.GET, request, Map.class);
    return exchange.getBody();
};
FutureTask<Map> futureTask = new FutureTask<Map>(task);
new Thread(futureTask).start();
Map result = futureTask.get();

使用CompletableFuture的代码如下所示:


RestTemplate restTemplate = new RestTemplate();
String url = "localhost:8080/index";

CompletableFuture<String> future = CompletableFuture.supplyAsync(() ->
        restTemplate.getForObject(url, String.class));

String result = future.get();

4. 自定义HttpMessageConverter

RestTemplate通过使用HttpMessageConverter将Http请求和响应转换为对象。默认情况下,HttpClient支持JSON和XML。如果您的服务端将数据提供为Jackson、Gson、XML或您自己的格式,您可以编写自定义消息转换器。

下面是一个自定义的消息转换器:


public class MappingJackson2CalendarHttpMessageConverter extends MappingJackson2HttpMessageConverter {

    public MappingJackson2CalendarHttpMessageConverter() {
        List<MediaType> mediaTypes = new ArrayList<>();
        mediaTypes.add(MediaType.APPLICATION_JSON);
        setSupportedMediaTypes(mediaTypes);
    }

    @Override
    protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        ObjectMapper mapper = getObjectMapper();
        ObjectWriter writer = mapper.writerWithView(Views.Public.class);
        writer.writeValue(outputMessage.getBody(), object);
    }

    @Override
    protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        ObjectMapper mapper = getObjectMapper();
        return mapper.readValue(inputMessage.getBody(), getJavaType(clazz));
    }
}

上述代码演示了继承MappingJackson2HttpMessageConverter并支持MediaType为application/json的文件格式。自定义的消息转换器MappingJackson2CalendarHttpMessageConverter允许您通过重写readInternal和writeInternal方法将请求和响应转换为所需的数据格式。

四、总结

RestTemplate是一个非常强大的HTTP客户端,可以用于与第三方REST服务进行通信,获取JSON/XML等数据,并对其进行处理。本文介绍了RestTemplate的基本用法、扩展用法、以及自定义实现HttpMessageConverter的用法。希望可以帮助到大家。