Code update for Spring RestTemplate Exception Handling article.

This commit is contained in:
jacques 2018-05-22 12:07:45 -04:00
parent d98b696baa
commit 9a04bf2c2c
7 changed files with 168 additions and 5 deletions

View File

@ -31,8 +31,14 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-test</artifactId>-->
<!--<scope>test</scope>-->
<!--</dependency>-->
<!-- Spring -->
@ -240,7 +246,7 @@
<artifactId>cargo-maven2-plugin</artifactId>
<version>${cargo-maven2-plugin.version}</version>
<configuration>
<wait>true</wait>
<!--<wait>true</wait> caused errors on commit-->
<container>
<containerId>tomcat8x</containerId>
<type>embedded</type>

View File

@ -1,8 +1,5 @@
package org.baeldung.config;
import java.text.SimpleDateFormat;
import java.util.List;
import org.baeldung.config.converter.KryoHttpMessageConverter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@ -19,6 +16,9 @@ import org.springframework.web.servlet.config.annotation.ContentNegotiationConfi
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.text.SimpleDateFormat;
import java.util.List;
/*
* Please note that main web configuration is in src/main/webapp/WEB-INF/api-servlet.xml
*/

View File

@ -0,0 +1,4 @@
package org.baeldung.web.exception;
public class NotFoundException extends RuntimeException {
}

View File

@ -0,0 +1,53 @@
package org.baeldung.web.handler;
import org.baeldung.web.exception.NotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.client.ResponseErrorHandler;
import java.io.IOException;
@Component
public class RestTemplateResponseErrorHandler implements ResponseErrorHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(RestTemplateResponseErrorHandler.class);
@Override
public boolean hasError(ClientHttpResponse httpResponse) throws IOException {
return (httpResponse
.getStatusCode()
.series() == HttpStatus.Series.CLIENT_ERROR || httpResponse
.getStatusCode()
.series() == HttpStatus.Series.SERVER_ERROR);
}
@Override
public void handleError(ClientHttpResponse httpResponse) throws IOException {
if (httpResponse
.getStatusCode()
.series() == HttpStatus.Series.SERVER_ERROR) {
this.handleServerError(httpResponse);
} else if (httpResponse
.getStatusCode()
.series() == HttpStatus.Series.CLIENT_ERROR) {
this.handleClientError(httpResponse);
}
}
private void handleServerError(ClientHttpResponse httpResponse) {
//Handle Server specific errors
}
private void handleClientError(ClientHttpResponse httpResponse) throws IOException {
//Handle Client specific errors
if (httpResponse.getStatusCode() == HttpStatus.NOT_FOUND) {
//Log details here...
LOGGER.info("Throwing NotFoundException...");
throw new NotFoundException();
}
}
}

View File

@ -0,0 +1,22 @@
package org.baeldung.web.model;
public class Bar {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,24 @@
package org.baeldung.web.service;
import org.baeldung.web.handler.RestTemplateResponseErrorHandler;
import org.baeldung.web.model.Bar;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class BarConsumerService {
@Autowired RestTemplateBuilder restTemplateBuilder;
public Bar fetchBarById(String barId) {
RestTemplate restTemplate = restTemplateBuilder
.errorHandler(new RestTemplateResponseErrorHandler())
.build();
return restTemplate.getForObject("/bars/4242", Bar.class);
}
}

View File

@ -0,0 +1,54 @@
package org.baeldung.web.handler;
import org.baeldung.web.dto.Bazz;
import org.baeldung.web.exception.NotFoundException;
import org.baeldung.web.model.Bar;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.client.ExpectedCount;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.web.client.RestTemplate;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {NotFoundException.class, Bar.class})
@RestClientTest
public class RestTemplateResponseErrorHandlerIntegrationTest {
private static final Logger LOGGER = LoggerFactory.getLogger(RestTemplateResponseErrorHandler.class);
@Autowired private MockRestServiceServer server;
@Autowired private RestTemplateBuilder builder;
@Test(expected = NotFoundException.class)
public void givenCallToRemoteApi_when404ErrorReceived_throwNotFoundException() {
Assert.assertNotNull(this.builder);
Assert.assertNotNull(this.server);
RestTemplate restTemplate = this.builder
.errorHandler(new RestTemplateResponseErrorHandler())
.build();
this.server
.expect(ExpectedCount.once(), requestTo("/bars/4242"))
.andExpect(method(HttpMethod.GET))
.andRespond(withStatus(HttpStatus.NOT_FOUND));
Bar response = restTemplate.getForObject("/bars/4242", Bar.class);
this.server.verify();
}
}