diff --git a/spring-security-rest/pom.xml b/spring-security-rest/pom.xml index 5650f9c700..af69b57de1 100644 --- a/spring-security-rest/pom.xml +++ b/spring-security-rest/pom.xml @@ -92,6 +92,13 @@ ${jstl.version} runtime + + + javax.validation + validation-api + ${javax.validation.version} + + @@ -283,6 +290,7 @@ 5.2.2.Final 3.0.1 + 1.1.0.Final 1.2 2.2.2 2.2.2 diff --git a/spring-security-rest/src/main/java/org/baeldung/persistence/model/Foo.java b/spring-security-rest/src/main/java/org/baeldung/persistence/model/Foo.java index 0124424f59..4fe925a7be 100644 --- a/spring-security-rest/src/main/java/org/baeldung/persistence/model/Foo.java +++ b/spring-security-rest/src/main/java/org/baeldung/persistence/model/Foo.java @@ -2,10 +2,14 @@ package org.baeldung.persistence.model; import java.io.Serializable; +import javax.validation.constraints.Size; + + public class Foo implements Serializable { private long id; + @Size(min = 5, max = 14) private String name; public Foo() { diff --git a/spring-security-rest/src/main/java/org/baeldung/web/CustomRestExceptionHandler.java b/spring-security-rest/src/main/java/org/baeldung/web/CustomRestExceptionHandler.java index b6e7a919b9..36ad2c16ff 100644 --- a/spring-security-rest/src/main/java/org/baeldung/web/CustomRestExceptionHandler.java +++ b/spring-security-rest/src/main/java/org/baeldung/web/CustomRestExceptionHandler.java @@ -3,6 +3,9 @@ package org.baeldung.web; import java.util.ArrayList; import java.util.List; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; + import org.springframework.beans.TypeMismatchException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -67,16 +70,6 @@ public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler { return new ResponseEntity(apiError, new HttpHeaders(), apiError.getStatus()); } - @ExceptionHandler({ MethodArgumentTypeMismatchException.class }) - public ResponseEntity handleMethodArgumentTypeMismatch(final MethodArgumentTypeMismatchException ex, final WebRequest request) { - logger.info(ex.getClass().getName()); - // - final String error = ex.getName() + " should be of type " + ex.getRequiredType().getName(); - - final ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), error); - return new ResponseEntity(apiError, new HttpHeaders(), apiError.getStatus()); - } - @Override protected ResponseEntity handleMissingServletRequestPart(final MissingServletRequestPartException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) { logger.info(ex.getClass().getName()); @@ -95,6 +88,32 @@ public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler { return new ResponseEntity(apiError, new HttpHeaders(), apiError.getStatus()); } + // + + @ExceptionHandler({ MethodArgumentTypeMismatchException.class }) + public ResponseEntity handleMethodArgumentTypeMismatch(final MethodArgumentTypeMismatchException ex, final WebRequest request) { + logger.info(ex.getClass().getName()); + // + final String error = ex.getName() + " should be of type " + ex.getRequiredType().getName(); + + final ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), error); + return new ResponseEntity(apiError, new HttpHeaders(), apiError.getStatus()); + } + + + @ExceptionHandler({ ConstraintViolationException.class }) + public ResponseEntity handleConstraintViolation(final ConstraintViolationException ex, final WebRequest request) { + logger.info(ex.getClass().getName()); + // + final List errors = new ArrayList(); + for (final ConstraintViolation violation : ex.getConstraintViolations()) { + errors.add(violation.getRootBeanClass().getName() + " " + violation.getPropertyPath() + ": " + violation.getMessage()); + } + + final ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), errors); + return new ResponseEntity(apiError, new HttpHeaders(), apiError.getStatus()); + } + // 404 @Override @@ -116,7 +135,7 @@ public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler { final StringBuilder builder = new StringBuilder(); builder.append(ex.getMethod()); builder.append(" method is not supported for this request. Supported methods are "); - ex.getSupportedMethods(); + ex.getSupportedHttpMethods().forEach(t -> builder.append(t + " ")); final ApiError apiError = new ApiError(HttpStatus.METHOD_NOT_ALLOWED, ex.getLocalizedMessage(), builder.toString()); return new ResponseEntity(apiError, new HttpHeaders(), apiError.getStatus()); @@ -131,7 +150,7 @@ public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler { final StringBuilder builder = new StringBuilder(); builder.append(ex.getContentType()); builder.append(" media type is not supported. Supported media types are "); - ex.getSupportedMediaTypes().forEach(t -> builder.append(t + ", ")); + ex.getSupportedMediaTypes().forEach(t -> builder.append(t + " ")); final ApiError apiError = new ApiError(HttpStatus.UNSUPPORTED_MEDIA_TYPE, ex.getLocalizedMessage(), builder.substring(0, builder.length() - 2)); return new ResponseEntity(apiError, new HttpHeaders(), apiError.getStatus()); @@ -143,6 +162,7 @@ public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler { @ExceptionHandler({ Exception.class }) public ResponseEntity handleAll(final Exception ex, final WebRequest request) { logger.info(ex.getClass().getName()); + logger.error("error", ex); // final ApiError apiError = new ApiError(HttpStatus.INTERNAL_SERVER_ERROR, ex.getLocalizedMessage(), "error occurred"); return new ResponseEntity(apiError, new HttpHeaders(), apiError.getStatus()); diff --git a/spring-security-rest/src/test/java/org/baeldung/web/FooLiveTest.java b/spring-security-rest/src/test/java/org/baeldung/web/FooLiveTest.java index f148d090e2..121b308407 100644 --- a/spring-security-rest/src/test/java/org/baeldung/web/FooLiveTest.java +++ b/spring-security-rest/src/test/java/org/baeldung/web/FooLiveTest.java @@ -32,9 +32,10 @@ public class FooLiveTest { assertEquals(HttpStatus.BAD_REQUEST, error.getStatus()); assertEquals(1, error.getErrors().size()); assertTrue(error.getErrors().get(0).contains("should be of type")); - } + + @Test public void whenNoHandlerForHttpRequest_thenNotFound() { final Response response = givenAuth().delete(URL_PREFIX + "/api/xx"); @@ -42,6 +43,8 @@ public class FooLiveTest { assertEquals(HttpStatus.NOT_FOUND, error.getStatus()); assertEquals(1, error.getErrors().size()); assertTrue(error.getErrors().get(0).contains("No handler found")); + System.out.println(response.asString()); + } @Test @@ -51,6 +54,8 @@ public class FooLiveTest { assertEquals(HttpStatus.METHOD_NOT_ALLOWED, error.getStatus()); assertEquals(1, error.getErrors().size()); assertTrue(error.getErrors().get(0).contains("Supported methods are")); + System.out.println(response.asString()); + } @Test @@ -60,6 +65,8 @@ public class FooLiveTest { assertEquals(HttpStatus.UNSUPPORTED_MEDIA_TYPE, error.getStatus()); assertEquals(1, error.getErrors().size()); assertTrue(error.getErrors().get(0).contains("media type is not supported")); + System.out.println(response.asString()); + } }