Branch processing by the return value of RestTemplate and the status code of ResponseEntity in Spring Boot

The method of getting the status code changes without setting DefaultResponseErrorHandler The answer was here, but I missed it.

environment

Java : 11 JUnit : 4.12 Spring Boot : 2.1.6

Common sample code regardless of whether it is set or not

SandboxApplication.java


@SpringBootApplication
public class SandboxApplication {

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

    //Roughly bean registration here
    @Bean
    public RestTemplate setRestTemplate(){
        return new RestTemplate();
    }
}

Hoge.java


class Hoge {
    String message;

    public Hoge(@JsonProperty("message") String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

SampleTest.java


@RunWith(SpringRunner.class)
@SpringBootTest
public class SampleTest {

    @Autowired
    RestTemplate restTemplate;
    @Autowired
    ObjectMapper objectMapper;
    @Autowired
    Sample sut;

    @Test
public void test() throws Exception {
        //2xx series: ex) OK
        setUpMockRestServer(HttpStatus.OK);
        assertThat(sut.getHoge().getMessage(), is("It's 200"));

        //4xx series error: ex) NOT_FOUND
        setUpMockRestServer(HttpStatus.NOT_FOUND);
        assertThat(sut.getHoge().getMessage(), is("It's 404"));

        //5xx series error: ex) INTERNAL_SERVER_ERROR
        setUpMockRestServer(HttpStatus.INTERNAL_SERVER_ERROR);
        assertThat(sut.getHoge().getMessage(), is("It's 500"));
    }

    private void setUpMockRestServer(HttpStatus status) throws JsonProcessingException {
        MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build();
        String response = objectMapper.writeValueAsString(new Hoge(status.value() + "That's right"));
        mockServer.expect(requestTo("https://hoges/1"))
                .andRespond(withStatus(status).body(response).contentType(MediaType.APPLICATION_JSON_UTF8));
    }
}

Do not set DefaultResponseErrorHandler

--In case of client error system (4xx), HttpClientErrorException --In case of server error system (5xx), HttpServerErrorException --In the case of the code you set yourself, ʻUnknownHttpStatusCodeException Each of the above needs to be handled bytry-catch`

Sample.java


@Component
public class Sample {

    RestTemplate restTemplate;

    public Sample(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public Hoge getHoge() {
        ResponseEntity<Hoge> response;
        try {
            response = restTemplate.getForEntity("https://hoges/1", Hoge.class);
        } catch (HttpClientErrorException | HttpServerErrorException e) {
            //Can be branched by statusCode
            int statusCode = e.getStatusCode().value();
            return new Hoge(statusCode + "That's right");
        }

        return response.getBody();
    }
}

Set DefaultResponseErrorHandler

This can be achieved by inheriting DefaultResponseErrorHandler and setting it to be unnecessary.

SampleResponseErrorHandler.java


@Component
public class SampleResponseErrorHandler extends DefaultResponseErrorHandler {
    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
        //By writing nothing, it does not raise an exception even if a server error and a client error occur.
    }
}

Sample.java


@Component
public class Sample {

    RestTemplate restTemplate;
    SampleResponseErrorHandler sampleResponseErrorHandler;

    public Sample(RestTemplate restTemplate, SampleResponseErrorHandler sampleResponseErrorHandler) {
        this.restTemplate = restTemplate;
        this.sampleResponseErrorHandler = sampleResponseErrorHandler;
    }

    public Hoge getHoge() {
        //Set your own Defined ErrorHandler in RestTemplate
        restTemplate.setErrorHandler(sampleResponseErrorHandler);
        ResponseEntity<Hoge> response = restTemplate.getForEntity("https://hoges/1", Hoge.class);
        //In the sample, it returns as it is, but here you can branch as much as you want with the status code that can be obtained from ResponseEntity
        return response.getBody();
    }
}

Summary

I wanted to get the status code and branch in detail, but I was addicted to not being able to pick it up with an exception.

Recommended Posts

Branch processing by the return value of RestTemplate and the status code of ResponseEntity in Spring Boot
Procedure to make the value of the property file visible in Spring Boot
Specify the encoding of static resources in Spring Boot
[For beginners] DI ~ The basics of DI and DI in Spring ~
[Java] How to get the key and value stored in Map by iterative processing
Check the behavior of getOne, findById, and query methods in Spring Boot + Spring Data JPA
Sample code that uses the Mustache template engine in Spring Boot
Get a proxy instance of the component itself in Spring Boot
Spring validation was important in the order of Form and BindingResult
Form that receives the value of the repeating item in Spring MVC
Write test code in Spring Boot
Order of processing in the program
Coexistence of Flyway in the embedded database (h2) of the development environment and the release database (SQL Server) with Spring Boot
Web application structure by Java and processing flow in the presentation layer
The content of the return value of executeBatch is different between 11g and 12c
Get the value of enum saved in DB by Rails with attribute_before_type_cast
[HTTP] Status code included in the HTTP response
[Java] Various methods to acquire the value stored in List by iterative processing
Organize the differences in behavior of @NotBlank, @NotEmpty, @NotNull with Spring Boot + Thymeleaf
Sample code for DB control by declarative transaction in Spring Boot + Spring Data JPA
How to set environment variables in the properties file of Spring boot application
Asynchronous processing with regular execution in Spring Boot
Store the AWS SDK return value in DynamoDB
Run a Spring Boot project in VS Code
Output request and response log in Spring Boot
The story of raising Spring Boot 1.5 series to 2.1 series
Let's check the feel of Spring Boot + Swagger 2.0
[Java / Spring Boot] Spring security ⑤ --Implementation of logout processing
View the Gradle task in the Spring Boot project
How to implement authentication process by specifying user name and password in Spring Boot
Takes out the HashMap value and returns the result sorted by the value of value as a list.
[ruby] How to assign a value to a hash by referring to the value and key of another hash
Pass arguments to the method and receive the result of the operation as a return value
Count the frequency of occurrence of words in a sentence by stream processing (Apache Apex)
Sample code to assign a value in a property file to a field of the expected type