Added example for spring boot exception handling
This commit is contained in:
parent
22e98e06ea
commit
684ee6040e
|
@ -1,3 +1,4 @@
|
|||
Module for the articles that are part of the Spring REST E-book:
|
||||
|
||||
1. [Bootstrap a Web Application with Spring 5](https://www.baeldung.com/bootstraping-a-web-application-with-spring-and-java-based-configuration)
|
||||
2. [Error Handling for REST with Spring](http://www.baeldung.com/exception-handling-for-rest-with-spring)
|
||||
|
|
|
@ -20,12 +20,22 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
<version>${htmlunit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -39,5 +49,6 @@
|
|||
|
||||
<properties>
|
||||
<start-class>com.baeldung.SpringBootRestApplication</start-class>
|
||||
<htmlunit.version>2.32</htmlunit.version>
|
||||
</properties>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.errorhandling.boot;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@SpringBootApplication
|
||||
@PropertySource("errorhandling-application.properties")
|
||||
public class ErrorHandlingBootApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ErrorHandlingBootApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.errorhandling.boot.configurations;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
|
||||
@Component
|
||||
public class MyCustomErrorAttributes extends DefaultErrorAttributes {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
|
||||
Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace);
|
||||
errorAttributes.put("locale", webRequest.getLocale()
|
||||
.toString());
|
||||
errorAttributes.remove("error");
|
||||
errorAttributes.put("cause", errorAttributes.get("message"));
|
||||
errorAttributes.remove("message");
|
||||
errorAttributes.put("status", String.valueOf(errorAttributes.get("status")));
|
||||
return errorAttributes;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.baeldung.errorhandling.boot.configurations;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.ErrorProperties;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
|
||||
import org.springframework.boot.web.servlet.error.ErrorAttributes;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Component
|
||||
public class MyErrorController extends BasicErrorController {
|
||||
|
||||
public MyErrorController(ErrorAttributes errorAttributes) {
|
||||
super(errorAttributes, new ErrorProperties());
|
||||
}
|
||||
|
||||
@RequestMapping(produces = MediaType.APPLICATION_XML_VALUE)
|
||||
public ResponseEntity<Map<String, Object>> xmlError(HttpServletRequest request) {
|
||||
Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.APPLICATION_XML));
|
||||
body.put("xmlkey", "the XML response is different!");
|
||||
HttpStatus status = getStatus(request);
|
||||
return new ResponseEntity<>(body, status);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.errorhandling.boot.web;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class FaultyRestController {
|
||||
|
||||
@GetMapping("/exception")
|
||||
public ResponseEntity<Void> requestWithException() {
|
||||
throw new NullPointerException("Error in the faulty controller!");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung;
|
||||
package com.baeldung.web;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
#server.error.whitelabel.enabled=false
|
||||
#server.error.include-stacktrace=always
|
|
@ -0,0 +1,65 @@
|
|||
package com.baeldung.errorhandling.boot;
|
||||
|
||||
import static io.restassured.RestAssured.given;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.hasKey;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.isA;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
|
||||
public class ErrorHandlingLiveTest {
|
||||
|
||||
private static final String BASE_URL = "http://localhost:8080";
|
||||
private static final String EXCEPTION_ENDPOINT = "/exception";
|
||||
|
||||
private static final String ERROR_RESPONSE_KEY_PATH = "error";
|
||||
private static final String XML_RESPONSE_KEY_PATH = "xmlkey";
|
||||
private static final String LOCALE_RESPONSE_KEY_PATH = "locale";
|
||||
private static final String CAUSE_RESPONSE_KEY_PATH = "cause";
|
||||
private static final String RESPONSE_XML_ROOT = "Map";
|
||||
private static final String XML_RESPONSE_KEY_XML_PATH = RESPONSE_XML_ROOT + "." + XML_RESPONSE_KEY_PATH;
|
||||
private static final String LOCALE_RESPONSE_KEY_XML_PATH = RESPONSE_XML_ROOT + "." + LOCALE_RESPONSE_KEY_PATH;
|
||||
private static final String CAUSE_RESPONSE_KEY_XML_PATH = RESPONSE_XML_ROOT + "." + CAUSE_RESPONSE_KEY_PATH;
|
||||
private static final String CAUSE_RESPONSE_VALUE = "Error in the faulty controller!";
|
||||
private static final String XML_RESPONSE_VALUE = "the XML response is different!";
|
||||
|
||||
@Test
|
||||
public void whenRequestingFaultyEndpointAsJson_thenReceiveDefaultResponseWithConfiguredAttrs() {
|
||||
given().header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
|
||||
.get(EXCEPTION_ENDPOINT)
|
||||
.then()
|
||||
.body("$", hasKey(LOCALE_RESPONSE_KEY_PATH))
|
||||
.body(CAUSE_RESPONSE_KEY_PATH, is(CAUSE_RESPONSE_VALUE))
|
||||
.body("$", not(hasKey(ERROR_RESPONSE_KEY_PATH)))
|
||||
.body("$", not(hasKey(XML_RESPONSE_KEY_PATH)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenRequestingFaultyEndpointAsXml_thenReceiveXmlResponseWithConfiguredAttrs() {
|
||||
given().header(HttpHeaders.ACCEPT, MediaType.APPLICATION_XML_VALUE)
|
||||
.get(EXCEPTION_ENDPOINT)
|
||||
.then()
|
||||
.body(LOCALE_RESPONSE_KEY_XML_PATH, isA(String.class))
|
||||
.body(CAUSE_RESPONSE_KEY_XML_PATH, is(CAUSE_RESPONSE_VALUE))
|
||||
.body(RESPONSE_XML_ROOT, not(hasKey(ERROR_RESPONSE_KEY_PATH)))
|
||||
.body(XML_RESPONSE_KEY_XML_PATH, is(XML_RESPONSE_VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenRequestingFaultyEndpointAsHtml_thenReceiveWhitelabelPageResponse() throws Exception {
|
||||
try (WebClient webClient = new WebClient()) {
|
||||
webClient.getOptions()
|
||||
.setThrowExceptionOnFailingStatusCode(false);
|
||||
HtmlPage page = webClient.getPage(BASE_URL + EXCEPTION_ENDPOINT);
|
||||
assertThat(page.getBody()
|
||||
.asText()).contains("Whitelabel Error Page");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.spring.boot.rest;
|
||||
package com.baeldung.web;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
|
|
@ -18,7 +18,6 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com
|
|||
- [Metrics for your Spring REST API](http://www.baeldung.com/spring-rest-api-metrics)
|
||||
- [Bootstrap a Web Application with Spring 4](http://www.baeldung.com/bootstraping-a-web-application-with-spring-and-java-based-configuration)
|
||||
- [Build a REST API with Spring and Java Config](http://www.baeldung.com/building-a-restful-web-service-with-spring-and-java-based-configuration)
|
||||
- [Error Handling for REST with Spring](http://www.baeldung.com/exception-handling-for-rest-with-spring)
|
||||
- [Spring Security Expressions - hasRole Example](https://www.baeldung.com/spring-security-expressions-basic)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue