logbook icon indicating copy to clipboard operation
logbook copied to clipboard

BufferingClientHttpResponseWrapper incompatible with SpringBoot 2.7.x

Open taxone opened this issue 8 months ago • 0 comments

Description

Registering LogbookClientHttpRequestInterceptor to Spring RestTemplate, causes an error when the application code tries to call the method:

org.springframework.http.client.ClientHttpResponse.getStatusCode()

because the return type is changed in SpringBoot 6. In fact, in Spring Boot 5 this method returns:

org.springframework.http.HttpStatus

but in Spring Boot 6 it returns:

org.springframework.http.HttpStatusCode

This issue is related to: https://github.com/zalando/logbook/issues/1580

Expected Behavior

Calling the method org.springframework.http.client.ClientHttpResponse.getStatusCode() should work fine.

Actual Behavior

Calling the method org.springframework.http.client.ClientHttpResponse.getStatusCode() raises this error:

java.lang.AbstractMethodError: org.zalando.logbook.spring.BufferingClientHttpResponseWrapper.getStatusCode()Lorg/springframework/http/HttpStatus;
	at eu.tasgroup.gpp.albo.credem.client.RestTemplateResponseErrorHandler.hasError(RestTemplateResponseErrorHandler.java:23) ~[classes/:na]
	at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:813) ~[spring-web-5.3.26.jar:5.3.26]
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:783) ~[spring-web-5.3.26.jar:5.3.26]
	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:717) ~[spring-web-5.3.26.jar:5.3.26]
	at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:608) ~[spring-web-5.3.26.jar:5.3.26]

Steps to Reproduce

  1. Register the LogbookClientHttpRequestInterceptor :
@Configuration
public class SpringArchetypeConfiguration {

	/**
	 * Creates the RestTemplate Bean to be injected and used in the application.
	 *
	 * @param restTemplateBuilder
	 * @return
	 */
	@Bean
	public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder,LogbookClientHttpRequestInterceptor logbookInterceptor) {

		RestTemplate template = restTemplateBuilder				
				.additionalInterceptors(logbookInterceptor)
				.build();
		template.setErrorHandler(new RestTemplateResponseErrorHandler());
		return template;
	}
}
  1. Register an org.springframework.web.client.ResponseErrorHandler bean:
@Component
public class RestTemplateResponseErrorHandler implements ResponseErrorHandler {

    

    @Override
    public boolean hasError(ClientHttpResponse httpResponse) throws IOException {
    	 return httpResponse.getStatusCode() != HttpStatus.OK;
    }

    @Override
    public void handleError(ClientHttpResponse httpResponse) throws IOException {
            ....
     }
}
  1. Send a Request
  2. Error happens when the statement httpResponse.getStatusCode() in the method hasError is called

Context

The workaround is replacing the hasError method with this code:

    public boolean hasError(ClientHttpResponse httpResponse) throws IOException {
        return httpResponse.getRawStatusCode() != 200;
    }

But I'm worried because this error could happens elsewhere in the application code, for example if the getStatusCode() method is called by an exetranal library or Spring framework code.

Your Environment

Spring Boot 2.7.17 LogBook 3.8.0

taxone avatar Jun 13 '24 07:06 taxone