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; } }