Issue
- I am writing a customize ResponseErrorHandler for all RestTemplate api call in application. This application is a Spring Boot application and written in Kotlin
My code:
ServiceApiErrorHandler.class
class ServiceApiErrorHandler(
@Autowired
val agentAuthService: AgentAuthService
) : DefaultResponseErrorHandler() {
companion object {
private val logger: LogService = LogServiceImpl(ServiceApiErrorHandler::class.java)
}
override fun hasError(response: ClientHttpResponse): Boolean {
return (response.statusCode.is4xxClientError || response.statusCode.is5xxServerError)
}
override fun handleError(response: ClientHttpResponse) {
logger.info("LOGIN AGAIN 1")
}
override fun handleError(url: URI, method: HttpMethod, response: ClientHttpResponse) {
if (response.statusCode == HttpStatus.UNAUTHORIZED && ServiceApiEnpoint.isServiceApiEndpoint(url = url.toString())) {
logger.info("LOGIN AGAIN")
agentAuthService.callLogin();
}
}
}
CustomRestTemplateCustomizer class
class CustomRestTemplateCustomizer(
@Autowired
val agentAuthService: AgentAuthService
) : RestTemplateCustomizer {
override fun customize(restTemplate: RestTemplate) {
restTemplate.errorHandler = ServiceApiErrorHandler(agentAuthService = agentAuthService)
}
}
ClientHttpConfig class
@Configuration
class ClientHttpConfig(
@Autowired
val agentAuthService: AgentAuthService
) {
@Bean
fun customRestTemplateCustomizer(): CustomRestTemplateCustomizer {
return CustomRestTemplateCustomizer(agentAuthService = agentAuthService);
}
}
The problem is when I run, RestTemplate still handle error using DefaultResponseErrorHandler and after debug, I quickly realize that the customize() method in class CustomRestTemplateCustomizer was never being called.
So my questions is:
- Is customize() method suppose to be automatic called? If not, how should i call it?
- Does my code is ok to implement customize ResponseErrorHandler?
Note: I follow the tutorial in Java: https://www.baeldung.com/spring-rest-template-builder to write this version in Kotlin.
Solution
how do you create the RestTemplate instance?
try adding a Bean, then the customizer should be used
@Configuration
class ClientHttpConfig(
@Autowired
val agentAuthService: AgentAuthService,
@Autowired val builder: RestTemplateBuilder
) {
@Bean
fun customRestTemplateCustomizer(): CustomRestTemplateCustomizer {
return CustomRestTemplateCustomizer(agentAuthService = agentAuthService);
}
@Bean
fun customizedRestTemplate(): RestTemplate {
return builder.build();
}
}
Edit: needs to be created by RestTemplateBuilder
Answered By - Marc Stroebel
Answer Checked By - Marie Seifert (JavaFixing Admin)