this is main class of my application
@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();
}
}
In multiple services and components, this RestTemplate is getting autowired.
Like in a controller this is getting used like
@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;
}
}
And in a different service like
@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));
}
}
Problem is this implementation throws
There was an unexpected error (type=Internal Server Error, status=500). I/O error on GET request for "http://xx.xxxxxx.xxx/xxxx/xxxx/xxxxxx":
This is getting produced intermitently, eventhough curl request for same works.
Something you could take a look to is you are auto wiring the RestTemplate singleton object and, however, every time the method is called it is adding the same message converter to the resttemplate.
Bear in mind that resttemplate is thread-safe once constructed, but deal with message converters may not be thread safe after construction. Have a look for example to this thread:
You could try to do something like below to have a resttemplate instance only for your service
@Service
public class DetailsQuery {
private final RestTemplate restTemplate;
@Autowired
public DetailsQuery (RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.additionalMessageConverters(new MappingJackson2HttpMessageConverter()) build();
}
....
}
Or do the same within a @Config
class creating the singleton Resttemplate object.