Spring Boot - @Value returning null in the @Component class

749 views Asked by At

This is a simple class where im trying to map a error message with @value.

i did not add the corresponding value in property file as i have set default value

@Slf4j
@Component
public class RestTemplateResponseErrorHandler
        implements ResponseErrorHandler {

    @Value("${invalid.password:test}")
    private String invalidPassword;


    @Override
    public boolean hasError(ClientHttpResponse httpResponse)
            throws IOException {

        return (
                httpResponse.getStatusCode().series() == CLIENT_ERROR
                        || httpResponse.getStatusCode().series() == SERVER_ERROR);
    }

    @Override
    public void handleError(ClientHttpResponse httpResponse)
            throws IOException {

        if (httpResponse.getStatusCode()
                .series() == SERVER_ERROR) {
            log.info("RestTemplateResponseErrorHandler --- SERVER_ERROR");
            // handle SERVER_ERROR
        } else if (httpResponse.getStatusCode()
                .series() == CLIENT_ERROR) {
            log.info("RestTemplateResponseErrorHandler --- CLIENT_ERROR");

            if (httpResponse.getStatusCode() == HttpStatus.BAD_REQUEST)
                throw new UnAuthorisedRequestException(invalidPassword);


        }
    }
}

here throw new UnAuthorisedRequestException(invalidPassword); returns null

Not sure what is the problem with the class as it is marked as @Component

@Configuration
public class CommonBeanConfig {

    @Bean
    public RestTemplate restTemplate(SSLSocketFactory sslSocketFactory) {
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(new SSLConnectionSocketFactory(sslSocketFactory, new NoopHostnameVerifier()))
                .build();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);
        RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(requestFactory));
        restTemplate.setInterceptors(Collections.singletonList(new ClientLoggingInterceptor()));
        restTemplate.setErrorHandler(new RestTemplateResponseErrorHandler());
        return restTemplate;
    }

}

This class is added as the exception handler

1

There are 1 answers

0
Mark Bramnik On

RestTemplateResponseErrorHandler in your example is not managed by spring - you create it "manually". So spring can't use @Value for objects that it doesn't manage.

Try the following:

@Configuration
public class CommonBeanConfig {

    @Bean
    public RestTemplateResponseErrorHandler restTemplateErrorHandler() {
      return new RestTemplateErrorHandler();
    }
    @Bean
    public RestTemplate restTemplate(SSLSocketFactory sslSocketFactory) {
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(new SSLConnectionSocketFactory(sslSocketFactory, new NoopHostnameVerifier()))
                .build();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);
        RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(requestFactory));
        restTemplate.setInterceptors(Collections.singletonList(new ClientLoggingInterceptor()));
        restTemplate.setErrorHandler(restTemplateErrorHandler()); // or inject the parameter into the method public RestTemplate restTemplate(SSLSocketFactory sslSocketFactory, RestTemplateErrorHandler restTemplateErrorHandler) 
        return restTemplate;
    }

}

Note, Since you're already using java config - you don't have to put @Component on the RestTemplateErrorHandler class.

If you do have to use @Component and want it to be found and instantiated by component scanning - don't create a bean for the error handler in the java config and work with method I've mentioned in comments of the restTemplate:

@Bean
public RestTemplate restTemplate(SSLSocketFactory sslSocketFactory, RestTemplateErrorHandler restTemplateErrorHandler) {
   ...
}