参考

0. 原因

我调用第三方接口时,第三方接口抛出异常!restTemplate 接收到异常之后
启用了自己的异常处理!
导致了第三方抛出的错误信息被覆盖,调用方不能准确的获取错误消息提示

1. 直接new

  1. private static RestTemplate restTemplate = new RestTemplate();
  2. // 错误处理
  3. restTemplate.setErrorHandler(new NoErrorResultErrorHandler());
  4. Map<String,Object> respMap = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Map.class).getBody();

2. 如果使用配置类

  1. package com.cr.code.eco.ecoapi.config;
  2. import org.apache.http.client.HttpClient;
  3. import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
  4. import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
  5. import org.apache.http.impl.client.HttpClientBuilder;
  6. import org.apache.http.impl.client.HttpClients;
  7. import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
  8. import org.springframework.context.annotation.Configuration;
  9. import org.springframework.http.HttpStatus;
  10. import org.springframework.http.client.ClientHttpResponse;
  11. import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
  12. import org.springframework.web.client.DefaultResponseErrorHandler;
  13. import org.springframework.web.client.RestTemplate;
  14. import java.io.IOException;
  15. import java.util.concurrent.TimeUnit;
  16. /**
  17. *
  18. * 解决RestTemplate 中高并发情况下Socket InteAddress 用尽
  19. * @参考: https://blog.csdn.net/qq_27217017/article/details/98601893
  20. *
  21. * @author tn
  22. * @version 1
  23. * @ClassName RestTemplateConfig
  24. * @description RestTemplate跟换底层
  25. * 高频且短的大量Request请求,控制 Request的请求量,不会跑出IntAddress use out的异常
  26. *
  27. * @date 2020/7/26 3:01
  28. */
  29. public class RestTemplateConfig {
  30. private static RestTemplate restTemplate;
  31. static {
  32. // 长链接保持时间长度20秒
  33. PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =
  34. new PoolingHttpClientConnectionManager(20, TimeUnit.SECONDS);
  35. // 设置最大链接数
  36. poolingHttpClientConnectionManager.setMaxTotal(2*getMaxCpuCore() + 3 );
  37. // 单路由的并发数
  38. poolingHttpClientConnectionManager.setDefaultMaxPerRoute(2*getMaxCpuCore());
  39. HttpClientBuilder httpClientBuilder = HttpClients.custom();
  40. httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
  41. // 重试次数3次,并开启
  42. httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3,true));
  43. HttpClient httpClient = httpClientBuilder.build();
  44. // 保持长链接配置,keep-alive
  45. httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());
  46. HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
  47. // 链接超时配置 5秒
  48. httpComponentsClientHttpRequestFactory.setConnectTimeout(5000);
  49. // 连接读取超时配置
  50. // httpComponentsClientHttpRequestFactory.setReadTimeout(10000);
  51. // 连接池不够用时候等待时间长度设置,分词那边 500毫秒 ,我们这边设置成1秒
  52. httpComponentsClientHttpRequestFactory.setConnectionRequestTimeout(3000);
  53. // 缓冲请求数据,POST大量数据,可以设定为true 我们这边机器比较内存较大
  54. httpComponentsClientHttpRequestFactory.setBufferRequestBody(true);
  55. restTemplate = new RestTemplate();
  56. restTemplate.setRequestFactory(httpComponentsClientHttpRequestFactory);
  57. //注意:如果不重写 handleError http抛出的异常会直接转发给前端项目中就获取不了接口返回值了
  58. restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
  59. @Override
  60. public void handleError(ClientHttpResponse response) throws IOException {
  61. if(response.getStatusCode() == HttpStatus.OK){
  62. super.handleError(response);
  63. }
  64. }
  65. });
  66. }
  67. public static RestTemplate getRestTemplate(){
  68. return restTemplate;
  69. }
  70. private static int getMaxCpuCore(){
  71. int cpuCore = Runtime.getRuntime().availableProcessors();
  72. return cpuCore;
  73. }
  74. }

使用:

  1. /**
  2. * http调用
  3. */
  4. private RestTemplate restTemplate = RestTemplateConfig.getRestTemplate();
  5. /**
  6. * @return
  7. */
  8. private List<EnvironmentDetectionResponseVo> test(){
  9. String body = restTemplate.getForEntity("http://url",String.class).getBody();
  10. JSONArray jsonArray = JSON.parseArray(body);
  11. EnvironmentDetectionResponseVo[] EnvironmentDetectionResponseVo = jsonArray.toJavaObject(EnvironmentDetectionResponseVo[].class);
  12. return Arrays.asList(EnvironmentDetectionResponseVo);
  13. }

3. 现象

3.1 不处理他的默认异常

image.png

3.2处理之后

image.png