下面提到的使用org.springframework.web.client.RestTemplate RestTemplate样式的潜在问题是什么?

时间:2017-03-22 13:54:15

标签: java spring http-headers apache-httpclient-4.x resttemplate

这是我的应用程序的主要类

@SpringBootApplication (scanBasePackages = { "com.xyz.*" })
@EnableAsync
@EnableAspectJAutoProxy (proxyTargetClass=true)
@EnableScheduling
public class XyzApplication {

    public static void main(String[] args) {
        SpringApplication.run(XyzApplication.class, args);
    }

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        builder.requestFactory(new HttpComponentsClientHttpRequestFactory());
        return builder.build();
    }
}

在多个服务和组件中,此RestTemplate正在自动装配。

在控制器中,这就像

一样被使用
@RestController
@RequestMapping({ "my-api" })
public class CommonController {

    @Autowired
    AppConfig appConfig;

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("check")
    public String pwa() {
        ResponseEntity<String> response = restTemplate.getForEntity(appConfig.getApiConfig().get("ApiURL"), String.class);
        if (HttpStatus.OK == response.getStatusCode()) {
            return response.getBody().toString();
        } else {
            Logger.error(this.getClass(), "Api is not working");
        }

        return null;

    }
}

等其他服务中
@Service
public class DetailsQuery {

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private RestTemplate restTemplate;

    @Async
    public Future<ConcurrentHashMap<String, Object>> getDetails(JSONObject object) throws InterruptedException, RestClientException {

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());

        HttpEntity<String> entity = new HttpEntity<String>(object.toString(), headers);

        Map<String, Object> jsonObject = restTemplate.postForObject(new URI(appConfig.getApiConfig().get("searchApi")), entity, Map.class);

        ConcurrentHashMap<String, Object> response = new ConcurrentHashMap<String, Object>();
        response.putAll(jsonObject);

        return new AsyncResult<ConcurrentHashMap<String,Object>>(new ConcurrentHashMap<>(response));

    }

}

问题是这个实现抛出

  

出现意外错误(type = Internal Server Error,   状态= 500)。 GET请求的I / O错误   “http://xx.xxxxxx.xxx/xxxx/xxxx/xxxxxx”:

这是间歇性的产生,尽管卷曲请求同样的工作。

1 个答案:

答案 0 :(得分:2)

您可以看一下的是您自动连接RestTemplate单​​例对象,但是,每次调用该方法时,它都会向resttemplate添加相同的消息转换器。

请记住,resttemplate一旦构造就是线程安全的,但是在构造之后处理消息转换器可能不是线程安全的。看一下这个帖子的例子:

Is RestTemplate thread safe?

您可以尝试执行以下操作,仅为您的服务设置resttemplate实例

@Service
public class DetailsQuery {

  private final RestTemplate restTemplate;

  @Autowired
  public DetailsQuery (RestTemplateBuilder restTemplateBuilder) {
    this.restTemplate = restTemplateBuilder.additionalMessageConverters(new MappingJackson2HttpMessageConverter()) build();
  }

  ....
}

或者在@Config类中创建单独的Resttemplate对象。