【SpringRest】RestTemplate

The RestTemplate provides a higher level API over HTTP client libraries

官方:https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#rest-resttemplate

  • RestTemplate: The original Spring REST client with a synchronous, template method API.  As of 5.0 the RestTemplate is in maintenance mode

  • WebClient: a non-blocking, reactive alternative that supports both synchronous and asynchronous as well as streaming scenarios. 后续推荐

参考:https://www.baeldung.com/rest-template    https://www.cnblogs.com/coder-qi/p/use-spring-RestTemplate.html    https://juejin.cn/post/6844903842065154061


需掌握的知识点:

  1、RestTemplate如何初始化,如何切换不同的底层实现:HttpURLConnection、HttpClient、

  2、提供的方法,如何使用

  3、如何自定义ErrorHandler、HttpConverter


一、如何初始化

    1)初始化RestTemplate bean  

  • 定义单独的@Configuration类,@Bean完成RestTemplate初始化(可根据情况指定不同的底层实现)         
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory();
simpleClientHttpRequestFactory.setReadTimeout(2000);
return new RestTemplate(simpleClientHttpRequestFactory);
}
  • 具体类使用@Autowired完成restTemplate注入

     2)切换RestTemplate不同的底层实现

         在上述bean定义类构造方法使用java.net.HttpURLConnection初始化;可以通过构造方法初始化切换其他实现 ClientHttpRequestFactory 接口具体实现类.

    样例:RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());

二、提供的方法

      如果方法异常,统一返回RestClientException异常

三、如何开发

URIs:Many of the RestTemplate methods accept a URI template and URI template variables, either as a String variable argument, or as Map<String,String>.

// 使用string变量
String result = restTemplate.getForObject("https://example.com/hotels/{hotel}/bookings/{booking}", String.class, "42", "21"); // 使用Map<String, String> Map<String, String> vars = Collections.singletonMap("hotel", "42"); String result = restTemplate.getForObject("https://example.com/hotels/{hotel}/rooms/{hotel}", String.class, vars);

   URI templates将自动编码, 样例:restTemplate.getForObject("https://example.com/hotel list", String.class);   // Results in request to "https://example.com/hotel%20list"

Headers: 使用exchanges()指定请求头

String uriTemplate = "https://example.com/hotels/{hotel}";
URI uri = UriComponentsBuilder.fromUriString(uriTemplate).build(42);

RequestEntity<Void> requestEntity = RequestEntity.get(uri).header("MyRequestHeader", "MyValue").build();
ResponseEntity<String> response = template.exchange(requestEntity, String.class);
// 响应header
String responseHeader = response.getHeaders().getFirst("MyResponseHeader");
//响应body String body
= response.getBody();

Body:Objects passed into and returned from RestTemplate methods are converted to and from raw content with the help of an HttpMessageConverter.

四、执行失败场景

RestTemplate执行失败抛出RestClientException异常

五、设置返回状态码

参考:https://www.bezkoder.com/spring-boot-controlleradvice-exceptionhandler/

1、如果controller定义返回具体类型,如String、User,则状态码200

2、如果抛出restClientException,则状态码500  

方法1:ResponseEntity extends HttpEntity:自定义状态码

       controller方法定义:返回ResponseEntity<User> xxx,

       实现: return new  ResponseEntity.ok(user).   或      return new ResponseEntity<>(user, HttpStatus.OK);       

样例中body为String类型

@GetMapping("/test")
public ResponseEntity<String> test() {
    String url = "http://www.baidu.com";
    try {
        restTemplate.getForEntity(url, String.class);
    } catch (RestClientException e)
    {
        return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
    return ResponseEntity.ok("SUCCESS");
}

方法2:方法上@ControllerAdvice + @ExceptionHandler + @ResponseStatus(value=HttpStatus.NOT_FOUND)

In the example above, we use @ControllerAdvice for REST web services and return ResponseEntity object additionally.

Spring also provides @ResponseBody annotation which tells a controller that the object returned is automatically serialized into JSON and passed it to the HttpResponse object. This way does not require ResponseEntity but you need to use @ResponseStatus to set the HTTP status code for that exception.

@ControllerAdvice
@ResponseBody
public class ControllerExceptionHandler {

  @ExceptionHandler(ResourceNotFoundException.class)
  @ResponseStatus(value = HttpStatus.NOT_FOUND)
  public ErrorMessage resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
    ErrorMessage message = new ErrorMessage(...);
    return message;
  }
}

  

原文地址:https://www.cnblogs.com/clarino/p/15715488.html