From 750316943350d7334521461918d34b9024efcda0 Mon Sep 17 00:00:00 2001 From: drohe Date: Fri, 24 Feb 2023 12:59:46 +0100 Subject: [PATCH 01/12] removed duplicate dependencies --- .gitignore | 31 +++++++++++++++++++++--- problem-spring-web-autoconfigure/pom.xml | 23 +----------------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 6003fdb1..f210ce2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,35 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + ### IntelliJ ### +*.iws *.iml +*.ipr .idea/ -### Maven ### -target/ -/.mvn/wrapper/*.jar +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ *.log diff --git a/problem-spring-web-autoconfigure/pom.xml b/problem-spring-web-autoconfigure/pom.xml index 0c5a0997..9b3ff69e 100644 --- a/problem-spring-web-autoconfigure/pom.xml +++ b/problem-spring-web-autoconfigure/pom.xml @@ -48,34 +48,13 @@ true - + - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.mockito - mockito-core - test - com.jayway.jsonpath json-path-assert test - - org.junit.jupiter - junit-jupiter-params - test - - - org.springframework - spring-test - test - org.springframework.boot spring-boot-starter-test From 2d105f26954694bb304fdb5f10644b19674a5622 Mon Sep 17 00:00:00 2001 From: drohe Date: Fri, 24 Feb 2023 13:00:16 +0100 Subject: [PATCH 02/12] removed handling for MissingServletRequestPartException --- .../MissingServletRequestPartAdviceTrait.java | 30 ------------------- .../advice/routing/RoutingAdviceTrait.java | 1 - ...singServletRequestPartAdviceTraitTest.java | 27 ----------------- 3 files changed, 58 deletions(-) delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestPartAdviceTrait.java delete mode 100644 problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestPartAdviceTraitTest.java diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestPartAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestPartAdviceTrait.java deleted file mode 100644 index 64d2c6c5..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestPartAdviceTrait.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.zalando.problem.spring.web.advice.routing; - -import org.apiguardian.api.API; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.multipart.support.MissingServletRequestPartException; -import org.zalando.problem.Problem; -import org.zalando.problem.Status; -import org.zalando.problem.spring.web.advice.AdviceTrait; - -import static org.apiguardian.api.API.Status.INTERNAL; -import static org.apiguardian.api.API.Status.STABLE; - -/** - * @see MissingServletRequestPartException - * @see Status#BAD_REQUEST - */ -@API(status = STABLE) -public interface MissingServletRequestPartAdviceTrait extends AdviceTrait { - - @API(status = INTERNAL) - @ExceptionHandler - default ResponseEntity handleMissingServletRequestPart( - final MissingServletRequestPartException exception, - final NativeWebRequest request) { - return create(Status.BAD_REQUEST, exception, request); - } - -} diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java index f3631398..e86be4d5 100644 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java @@ -11,7 +11,6 @@ @API(status = STABLE) public interface RoutingAdviceTrait extends MissingServletRequestParameterAdviceTrait, - MissingServletRequestPartAdviceTrait, NoHandlerFoundAdviceTrait, ServletRequestBindingAdviceTrait { } diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestPartAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestPartAdviceTraitTest.java deleted file mode 100644 index 01d43774..00000000 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestPartAdviceTraitTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.zalando.problem.spring.web.advice.routing; - -import org.junit.jupiter.api.Test; -import org.zalando.problem.spring.web.advice.AdviceTraitTesting; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -final class MissingServletRequestPartAdviceTraitTest implements AdviceTraitTesting { - - @Test - void handlesMultipart() throws Exception { - mvc().perform(multipart("http://localhost/api/handler-multipart") - .file("payload1", new byte[]{0x1})) - .andExpect(status().isBadRequest()) - .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Bad Request"))) - .andExpect(jsonPath("$.status", is(400))) - .andExpect(jsonPath("$.detail", containsString("payload2"))); - } - -} From ea317757ff7e60e1f9d29bf6e84612149adb711e Mon Sep 17 00:00:00 2001 From: drohe Date: Fri, 24 Feb 2023 17:01:44 +0100 Subject: [PATCH 03/12] removed handling of NoHandlerFoundException --- .../routing/NoHandlerFoundAdviceTrait.java | 39 ------------- .../advice/routing/RoutingAdviceTrait.java | 1 - .../NoHandlerFoundAdviceTraitTest.java | 55 ------------------- 3 files changed, 95 deletions(-) delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/NoHandlerFoundAdviceTrait.java delete mode 100644 problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/NoHandlerFoundAdviceTraitTest.java diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/NoHandlerFoundAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/NoHandlerFoundAdviceTrait.java deleted file mode 100644 index 15dcae24..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/NoHandlerFoundAdviceTrait.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.zalando.problem.spring.web.advice.routing; - -import org.apiguardian.api.API; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.servlet.DispatcherServlet; -import org.springframework.web.servlet.NoHandlerFoundException; -import org.zalando.problem.Problem; -import org.zalando.problem.Status; -import org.zalando.problem.spring.web.advice.AdviceTrait; - -import static org.apiguardian.api.API.Status.INTERNAL; -import static org.apiguardian.api.API.Status.STABLE; - -/** - * Transforms {@link NoHandlerFoundException NoHandlerFoundExceptions} into {@link Status#NOT_FOUND not-found} - * {@link Problem problems}. - *

- * Note: This requires {@link DispatcherServlet#setThrowExceptionIfNoHandlerFound(boolean)} being set - * to true. - *

- * - * @see NoHandlerFoundException - * @see Status#NOT_FOUND - * @see DispatcherServlet#setThrowExceptionIfNoHandlerFound(boolean) - */ -@API(status = STABLE) -public interface NoHandlerFoundAdviceTrait extends AdviceTrait { - - @API(status = INTERNAL) - @ExceptionHandler - default ResponseEntity handleNoHandlerFound( - final NoHandlerFoundException exception, - final NativeWebRequest request) { - return create(Status.NOT_FOUND, exception, request); - } - -} diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java index e86be4d5..48461b88 100644 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java @@ -11,6 +11,5 @@ @API(status = STABLE) public interface RoutingAdviceTrait extends MissingServletRequestParameterAdviceTrait, - NoHandlerFoundAdviceTrait, ServletRequestBindingAdviceTrait { } diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/NoHandlerFoundAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/NoHandlerFoundAdviceTraitTest.java deleted file mode 100644 index 5e8a7bf5..00000000 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/NoHandlerFoundAdviceTraitTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.zalando.problem.spring.web.advice.routing; - -import org.junit.jupiter.api.Test; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.web.servlet.DispatcherServlet; -import org.zalando.problem.spring.web.advice.AdviceTraitTesting; - -import java.lang.reflect.Field; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.springframework.http.HttpMethod.GET; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -final class NoHandlerFoundAdviceTraitTest implements AdviceTraitTesting { - - @Test - void noHandlerInController() throws Exception { - final MockMvc mvc = mvc(); - throwExceptionIfNoHandlerFound(mvc); - - mvc.perform(request(GET, "http://localhost/api/no-handler")) - .andExpect(status().isNotFound()) - .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Not Found"))) - .andExpect(jsonPath("$.status", is(404))) - .andExpect(jsonPath("$.detail", containsString("No endpoint GET"))); - } - - @Test - void noHandler() throws Exception { - final MockMvc mvc = mvc(); - throwExceptionIfNoHandlerFound(mvc); - - mvc.perform(request(GET, "http://localhost/no-handler")) - .andExpect(status().isNotFound()) - .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Not Found"))) - .andExpect(jsonPath("$.status", is(404))) - .andExpect(jsonPath("$.detail", containsString("No endpoint GET"))); - } - - private void throwExceptionIfNoHandlerFound(final MockMvc mvc) throws NoSuchFieldException, IllegalAccessException { - final Field field = MockMvc.class.getDeclaredField("servlet"); - field.setAccessible(true); - final DispatcherServlet servlet = (DispatcherServlet) field.get(mvc); - servlet.setThrowExceptionIfNoHandlerFound(true); - } - -} From 0993bb639aeb382d3c5d3788b1063027d674e157 Mon Sep 17 00:00:00 2001 From: drohe Date: Fri, 24 Feb 2023 17:15:33 +0100 Subject: [PATCH 04/12] removed handling of ServletRequestBindingException --- .../advice/routing/RoutingAdviceTrait.java | 3 +- .../ServletRequestBindingAdviceTrait.java | 30 ------------------- .../ServletRequestBindingAdviceTraitTest.java | 27 ----------------- 3 files changed, 1 insertion(+), 59 deletions(-) delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/ServletRequestBindingAdviceTrait.java delete mode 100644 problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/ServletRequestBindingAdviceTraitTest.java diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java index 48461b88..100bc12c 100644 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java @@ -10,6 +10,5 @@ */ @API(status = STABLE) public interface RoutingAdviceTrait extends - MissingServletRequestParameterAdviceTrait, - ServletRequestBindingAdviceTrait { + MissingServletRequestParameterAdviceTrait { } diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/ServletRequestBindingAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/ServletRequestBindingAdviceTrait.java deleted file mode 100644 index 064efbae..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/ServletRequestBindingAdviceTrait.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.zalando.problem.spring.web.advice.routing; - -import org.apiguardian.api.API; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.ServletRequestBindingException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.context.request.NativeWebRequest; -import org.zalando.problem.Problem; -import org.zalando.problem.Status; -import org.zalando.problem.spring.web.advice.AdviceTrait; - -import static org.apiguardian.api.API.Status.INTERNAL; -import static org.apiguardian.api.API.Status.STABLE; - -/** - * @see ServletRequestBindingException - * @see Status#BAD_REQUEST - */ -@API(status = STABLE) -public interface ServletRequestBindingAdviceTrait extends AdviceTrait { - - @API(status = INTERNAL) - @ExceptionHandler - default ResponseEntity handleServletRequestBinding( - final ServletRequestBindingException exception, - final NativeWebRequest request) { - return create(Status.BAD_REQUEST, exception, request); - } - -} diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/ServletRequestBindingAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/ServletRequestBindingAdviceTraitTest.java deleted file mode 100644 index fbc63b82..00000000 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/ServletRequestBindingAdviceTraitTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.zalando.problem.spring.web.advice.routing; - -import org.junit.jupiter.api.Test; -import org.zalando.problem.spring.web.advice.AdviceTraitTesting; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.springframework.http.HttpMethod.GET; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -final class ServletRequestBindingAdviceTraitTest implements AdviceTraitTesting { - - @Test - void servletRequestBinding() throws Exception { - mvc().perform(request(GET, "http://localhost/api/handler-headers")) - .andExpect(status().isBadRequest()) - .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Bad Request"))) - .andExpect(jsonPath("$.status", is(400))) - .andExpect(jsonPath("$.detail", containsString("X-Custom-Header"))); - } - -} From 22d2af0f122d89e76046c404ce8a2c99feb0724f Mon Sep 17 00:00:00 2001 From: drohe Date: Fri, 24 Feb 2023 17:26:44 +0100 Subject: [PATCH 05/12] removed handling of MissingServletRequestParameterException --- ...ingServletRequestParameterAdviceTrait.java | 30 ------------------- .../advice/routing/RoutingAdviceTrait.java | 3 +- ...ervletRequestParameterAdviceTraitTest.java | 27 ----------------- 3 files changed, 1 insertion(+), 59 deletions(-) delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestParameterAdviceTrait.java delete mode 100644 problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestParameterAdviceTraitTest.java diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestParameterAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestParameterAdviceTrait.java deleted file mode 100644 index 38c7afdb..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestParameterAdviceTrait.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.zalando.problem.spring.web.advice.routing; - -import org.apiguardian.api.API; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.MissingServletRequestParameterException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.context.request.NativeWebRequest; -import org.zalando.problem.Problem; -import org.zalando.problem.Status; -import org.zalando.problem.spring.web.advice.AdviceTrait; - -import static org.apiguardian.api.API.Status.INTERNAL; -import static org.apiguardian.api.API.Status.STABLE; - -/** - * @see MissingServletRequestParameterException - * @see Status#BAD_REQUEST - */ -@API(status = STABLE) -public interface MissingServletRequestParameterAdviceTrait extends AdviceTrait { - - @API(status = INTERNAL) - @ExceptionHandler - default ResponseEntity handleMissingServletRequestParameter( - final MissingServletRequestParameterException exception, - final NativeWebRequest request) { - return create(Status.BAD_REQUEST, exception, request); - } - -} diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java index 100bc12c..33cca58d 100644 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java @@ -9,6 +9,5 @@ * @see AdviceTrait */ @API(status = STABLE) -public interface RoutingAdviceTrait extends - MissingServletRequestParameterAdviceTrait { +public interface RoutingAdviceTrait { } diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestParameterAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestParameterAdviceTraitTest.java deleted file mode 100644 index fe1562fe..00000000 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/routing/MissingServletRequestParameterAdviceTraitTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.zalando.problem.spring.web.advice.routing; - -import org.junit.jupiter.api.Test; -import org.zalando.problem.spring.web.advice.AdviceTraitTesting; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.springframework.http.HttpMethod.GET; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -final class MissingServletRequestParameterAdviceTraitTest implements AdviceTraitTesting { - - @Test - void missingServletRequestParameter() throws Exception { - mvc().perform(request(GET, "http://localhost/api/handler-params")) - .andExpect(status().isBadRequest()) - .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Bad Request"))) - .andExpect(jsonPath("$.status", is(400))) - .andExpect(jsonPath("$.detail", containsString("params1"))); - } - -} From 3ec3ed742e8980fa763f42d0979d7cb74c874d81 Mon Sep 17 00:00:00 2001 From: drohe Date: Fri, 24 Feb 2023 17:42:34 +0100 Subject: [PATCH 06/12] removed RoutingAdviceTrait --- .../problem/spring/web/advice/AdviceTrait.java | 2 -- .../problem/spring/web/advice/ProblemHandling.java | 3 --- .../web/advice/routing/RoutingAdviceTrait.java | 13 ------------- .../spring/web/advice/routing/package-info.java | 5 ----- 4 files changed, 23 deletions(-) delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/package-info.java diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/AdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/AdviceTrait.java index c5b73304..f47ecc76 100644 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/AdviceTrait.java +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/AdviceTrait.java @@ -25,7 +25,6 @@ import org.zalando.problem.spring.web.advice.http.HttpAdviceTrait; import org.zalando.problem.spring.web.advice.io.IOAdviceTrait; import org.zalando.problem.spring.web.advice.network.NetworkAdviceTrait; -import org.zalando.problem.spring.web.advice.routing.RoutingAdviceTrait; import org.zalando.problem.spring.web.advice.validation.ValidationAdviceTrait; import jakarta.servlet.http.HttpServletResponse; @@ -62,7 +61,6 @@ * @see HttpAdviceTrait * @see IOAdviceTrait * @see NetworkAdviceTrait - * @see RoutingAdviceTrait * @see ValidationAdviceTrait */ @API(status = STABLE) diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/ProblemHandling.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/ProblemHandling.java index 79a91efe..14b35430 100644 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/ProblemHandling.java +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/ProblemHandling.java @@ -6,7 +6,6 @@ import org.zalando.problem.spring.web.advice.http.HttpAdviceTrait; import org.zalando.problem.spring.web.advice.io.IOAdviceTrait; import org.zalando.problem.spring.web.advice.network.NetworkAdviceTrait; -import org.zalando.problem.spring.web.advice.routing.RoutingAdviceTrait; import org.zalando.problem.spring.web.advice.validation.ValidationAdviceTrait; import static org.apiguardian.api.API.Status.STABLE; @@ -25,7 +24,6 @@ * @see GeneralAdviceTrait * @see HttpAdviceTrait * @see IOAdviceTrait - * @see RoutingAdviceTrait * @see ValidationAdviceTrait */ @API(status = STABLE) @@ -34,7 +32,6 @@ public interface ProblemHandling extends HttpAdviceTrait, IOAdviceTrait, NetworkAdviceTrait, - RoutingAdviceTrait, ValidationAdviceTrait { } diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java deleted file mode 100644 index 33cca58d..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/RoutingAdviceTrait.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.zalando.problem.spring.web.advice.routing; - -import org.apiguardian.api.API; -import org.zalando.problem.spring.web.advice.AdviceTrait; - -import static org.apiguardian.api.API.Status.STABLE; - -/** - * @see AdviceTrait - */ -@API(status = STABLE) -public interface RoutingAdviceTrait { -} diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/package-info.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/package-info.java deleted file mode 100644 index 1ed00ec1..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/routing/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -@ParametersAreNonnullByDefault -package org.zalando.problem.spring.web.advice.routing; - -import javax.annotation.ParametersAreNonnullByDefault; - From 802ba476d2ec99b062db9ce4ee373a02184f866d Mon Sep 17 00:00:00 2001 From: drohe Date: Fri, 24 Feb 2023 17:56:09 +0100 Subject: [PATCH 07/12] removed handling of HttpRequestMethodNotSupportedException --- .../web/advice/http/HttpAdviceTrait.java | 3 +- .../http/MethodNotAllowedAdviceTrait.java | 44 -------------- .../http/MethodNotAllowedAdviceTraitTest.java | 57 ------------------- 3 files changed, 1 insertion(+), 103 deletions(-) delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/MethodNotAllowedAdviceTrait.java delete mode 100644 problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/http/MethodNotAllowedAdviceTraitTest.java diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/HttpAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/HttpAdviceTrait.java index 6563366a..3a13b104 100644 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/HttpAdviceTrait.java +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/HttpAdviceTrait.java @@ -11,7 +11,6 @@ @API(status = STABLE) public interface HttpAdviceTrait extends NotAcceptableAdviceTrait, - UnsupportedMediaTypeAdviceTrait, - MethodNotAllowedAdviceTrait { + UnsupportedMediaTypeAdviceTrait { } diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/MethodNotAllowedAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/MethodNotAllowedAdviceTrait.java deleted file mode 100644 index d0ba6ff4..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/MethodNotAllowedAdviceTrait.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.zalando.problem.spring.web.advice.http; - -import com.google.gag.annotation.remark.Facepalm; -import com.google.gag.annotation.remark.WTF; -import org.apiguardian.api.API; -import org.springframework.http.HttpHeaders; -import org.springframework.http.ResponseEntity; -import org.springframework.web.HttpRequestMethodNotSupportedException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.context.request.NativeWebRequest; -import org.zalando.problem.Problem; -import org.zalando.problem.Status; -import org.zalando.problem.spring.web.advice.AdviceTrait; - -import javax.annotation.Nullable; - -import static java.util.Objects.requireNonNull; -import static org.apiguardian.api.API.Status.INTERNAL; -import static org.apiguardian.api.API.Status.STABLE; - -@API(status = STABLE) -public interface MethodNotAllowedAdviceTrait extends AdviceTrait { - - @API(status = INTERNAL) - @ExceptionHandler - default ResponseEntity handleRequestMethodNotSupportedException( - final HttpRequestMethodNotSupportedException exception, - final NativeWebRequest request) { - - @WTF - @Facepalm("Nullable arrays... great work from Spring :/") - @Nullable final String[] methods = exception.getSupportedMethods(); - - if (methods == null || methods.length == 0) { - return create(Status.METHOD_NOT_ALLOWED, exception, request); - } - - final HttpHeaders headers = new HttpHeaders(); - headers.setAllow(requireNonNull(exception.getSupportedHttpMethods())); - - return create(Status.METHOD_NOT_ALLOWED, exception, request, headers); - } - -} diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/http/MethodNotAllowedAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/http/MethodNotAllowedAdviceTraitTest.java deleted file mode 100644 index 78d887d2..00000000 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/http/MethodNotAllowedAdviceTraitTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.zalando.problem.spring.web.advice.http; - -import org.junit.jupiter.api.Test; -import org.springframework.http.ResponseEntity; -import org.springframework.web.HttpRequestMethodNotSupportedException; -import org.springframework.web.context.request.NativeWebRequest; -import org.zalando.problem.Problem; -import org.zalando.problem.spring.web.advice.AdviceTraitTesting; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.collection.IsMapContaining.hasKey; -import static org.mockito.Mockito.mock; -import static org.springframework.http.HttpMethod.POST; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -final class MethodNotAllowedAdviceTraitTest implements AdviceTraitTesting { - - @Test - public void methodNotAllowed() throws Exception { - mvc().perform(request(POST, "http://localhost/api/handler-problem") - .accept("application/x.bla+json", "application/problem+json")) - .andExpect(status().isMethodNotAllowed()) - .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(header().string("Allow", is("GET"))) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Method Not Allowed"))) - .andExpect(jsonPath("$.status", is(405))) - .andExpect(jsonPath("$.detail", containsString("not supported"))); - } - - @Test - void noAllowIfNullAllowed() { - final MethodNotAllowedAdviceTrait unit = new MethodNotAllowedAdviceTrait() { - }; - final ResponseEntity entity = unit.handleRequestMethodNotSupportedException( - new HttpRequestMethodNotSupportedException("non allowed"), mock(NativeWebRequest.class)); - - assertThat(entity.getHeaders(), not(hasKey("Allow"))); - } - - @Test - void noAllowIfNoneAllowed() { - final MethodNotAllowedAdviceTrait unit = new MethodNotAllowedAdviceTrait() { - }; - final ResponseEntity entity = unit.handleRequestMethodNotSupportedException( - new HttpRequestMethodNotSupportedException("non allowed", new String[]{}), mock(NativeWebRequest.class)); - - assertThat(entity.getHeaders(), not(hasKey("Allow"))); - } - -} From 2b1cac93810bfc51302fbf4a7318f9aed4e0244b Mon Sep 17 00:00:00 2001 From: drohe Date: Fri, 24 Feb 2023 19:04:28 +0100 Subject: [PATCH 08/12] removed handling of HttpMediaTypeException subclasses --- .../web/advice/http/HttpAdviceTrait.java | 4 +- .../advice/http/NotAcceptableAdviceTrait.java | 30 -------------- .../http/UnsupportedMediaTypeAdviceTrait.java | 35 ---------------- .../http/NotAcceptableAdviceTraitTest.java | 40 ------------------- .../UnsupportedMediaTypeAdviceTraitTest.java | 38 ------------------ 5 files changed, 1 insertion(+), 146 deletions(-) delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/NotAcceptableAdviceTrait.java delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/UnsupportedMediaTypeAdviceTrait.java delete mode 100644 problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/http/NotAcceptableAdviceTraitTest.java delete mode 100644 problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/http/UnsupportedMediaTypeAdviceTraitTest.java diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/HttpAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/HttpAdviceTrait.java index 3a13b104..ff0044b2 100644 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/HttpAdviceTrait.java +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/HttpAdviceTrait.java @@ -9,8 +9,6 @@ * @see AdviceTrait */ @API(status = STABLE) -public interface HttpAdviceTrait extends - NotAcceptableAdviceTrait, - UnsupportedMediaTypeAdviceTrait { +public interface HttpAdviceTrait { } diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/NotAcceptableAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/NotAcceptableAdviceTrait.java deleted file mode 100644 index a383df47..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/NotAcceptableAdviceTrait.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.zalando.problem.spring.web.advice.http; - -import org.apiguardian.api.API; -import org.springframework.http.ResponseEntity; -import org.springframework.web.HttpMediaTypeNotAcceptableException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.context.request.NativeWebRequest; -import org.zalando.problem.Problem; -import org.zalando.problem.Status; -import org.zalando.problem.spring.web.advice.AdviceTrait; - -import static org.apiguardian.api.API.Status.INTERNAL; -import static org.apiguardian.api.API.Status.STABLE; - -/** - * @see HttpMediaTypeNotAcceptableException - * @see Status#NOT_ACCEPTABLE - */ -@API(status = STABLE) -public interface NotAcceptableAdviceTrait extends AdviceTrait { - - @API(status = INTERNAL) - @ExceptionHandler - default ResponseEntity handleMediaTypeNotAcceptable( - final HttpMediaTypeNotAcceptableException exception, - final NativeWebRequest request) { - return create(Status.NOT_ACCEPTABLE, exception, request); - } - -} diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/UnsupportedMediaTypeAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/UnsupportedMediaTypeAdviceTrait.java deleted file mode 100644 index 0e948a85..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/UnsupportedMediaTypeAdviceTrait.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.zalando.problem.spring.web.advice.http; - -import org.apiguardian.api.API; -import org.springframework.http.HttpHeaders; -import org.springframework.http.ResponseEntity; -import org.springframework.web.HttpMediaTypeNotSupportedException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.context.request.NativeWebRequest; -import org.zalando.problem.Problem; -import org.zalando.problem.Status; -import org.zalando.problem.spring.web.advice.AdviceTrait; - -import static org.apiguardian.api.API.Status.INTERNAL; -import static org.apiguardian.api.API.Status.STABLE; - -/** - * @see HttpMediaTypeNotSupportedException - * @see Status#UNSUPPORTED_MEDIA_TYPE - */ -@API(status = STABLE) -public interface UnsupportedMediaTypeAdviceTrait extends AdviceTrait { - - @API(status = INTERNAL) - @ExceptionHandler - default ResponseEntity handleMediaTypeNotSupportedException( - final HttpMediaTypeNotSupportedException exception, - final NativeWebRequest request) { - - final HttpHeaders headers = new HttpHeaders(); - headers.setAccept(exception.getSupportedMediaTypes()); - - return create(Status.UNSUPPORTED_MEDIA_TYPE, exception, request, headers); - } - -} diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/http/NotAcceptableAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/http/NotAcceptableAdviceTraitTest.java deleted file mode 100644 index 0cd5a3a6..00000000 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/http/NotAcceptableAdviceTraitTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.zalando.problem.spring.web.advice.http; - -import org.junit.jupiter.api.Test; -import org.zalando.problem.spring.web.advice.AdviceTraitTesting; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.springframework.http.HttpMethod.GET; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -final class NotAcceptableAdviceTraitTest implements AdviceTraitTesting { - - @Test - void notAcceptable() throws Exception { - mvc().perform(request(GET, "http://localhost/api/handler-ok") - .accept("application/x.vnd.specific+json")) - .andExpect(status().isNotAcceptable()) - .andExpect(content().contentType("application/problem+json")) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Not Acceptable"))) - .andExpect(jsonPath("$.status", is(406))) - .andExpect(jsonPath("$.detail", containsString("No acceptable representation"))); - } - - @Test - void notAcceptableNoProblem() throws Exception { - mvc().perform(request(GET, "http://localhost/api/handler-ok") - .accept("image/png")) - .andExpect(status().isNotAcceptable()) - .andExpect(content().contentType("application/problem+json")) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Not Acceptable"))) - .andExpect(jsonPath("$.status", is(406))) - .andExpect(jsonPath("$.detail", containsString("No acceptable representation"))); - } - -} diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/http/UnsupportedMediaTypeAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/http/UnsupportedMediaTypeAdviceTraitTest.java deleted file mode 100644 index 4bdafa3f..00000000 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/http/UnsupportedMediaTypeAdviceTraitTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.zalando.problem.spring.web.advice.http; - -import org.junit.jupiter.api.Test; -import org.zalando.problem.spring.web.advice.AdviceTraitTesting; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.springframework.http.HttpMethod.PUT; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -final class UnsupportedMediaTypeAdviceTraitTest implements AdviceTraitTesting { - - @Test - void unsupportedMediaType() throws Exception { - mvc().perform(request(PUT, "http://localhost/api/handler-put") - .contentType("application/atom+xml")) - .andExpect(status().isUnsupportedMediaType()) - .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(header().string("Accept", containsString("application/json"))) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Unsupported Media Type"))) - .andExpect(jsonPath("$.status", is(415))) - .andExpect(jsonPath("$.detail", containsString("application/atom+xml"))); - } - - @Test - void acceptHeaderIfSupported() throws Exception { - mvc().perform(request(PUT, "http://localhost/api/handler-put") - .contentType("application/atom+xml")) - .andExpect(status().isUnsupportedMediaType()) - .andExpect(header().string("Accept", containsString("application/json"))) - .andExpect(header().string("Accept", containsString("application/xml"))); - } - -} From f30e36b4266af43a4964fc4fac077b73da2a75bb Mon Sep 17 00:00:00 2001 From: drohe Date: Fri, 24 Feb 2023 19:11:51 +0100 Subject: [PATCH 09/12] removed HttpAdviceTrait --- .../problem/spring/web/advice/AdviceTrait.java | 2 -- .../problem/spring/web/advice/ProblemHandling.java | 3 --- .../spring/web/advice/http/HttpAdviceTrait.java | 14 -------------- .../spring/web/advice/http/package-info.java | 5 ----- 4 files changed, 24 deletions(-) delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/HttpAdviceTrait.java delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/package-info.java diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/AdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/AdviceTrait.java index f47ecc76..4b1925ae 100644 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/AdviceTrait.java +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/AdviceTrait.java @@ -22,7 +22,6 @@ import org.zalando.problem.spring.common.AdviceTraits; import org.zalando.problem.spring.web.advice.custom.CustomAdviceTrait; import org.zalando.problem.spring.web.advice.general.GeneralAdviceTrait; -import org.zalando.problem.spring.web.advice.http.HttpAdviceTrait; import org.zalando.problem.spring.web.advice.io.IOAdviceTrait; import org.zalando.problem.spring.web.advice.network.NetworkAdviceTrait; import org.zalando.problem.spring.web.advice.validation.ValidationAdviceTrait; @@ -58,7 +57,6 @@ * @see ProblemHandling * @see CustomAdviceTrait * @see GeneralAdviceTrait - * @see HttpAdviceTrait * @see IOAdviceTrait * @see NetworkAdviceTrait * @see ValidationAdviceTrait diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/ProblemHandling.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/ProblemHandling.java index 14b35430..2f14bc22 100644 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/ProblemHandling.java +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/ProblemHandling.java @@ -3,7 +3,6 @@ import org.apiguardian.api.API; import org.zalando.problem.spring.web.advice.custom.CustomAdviceTrait; import org.zalando.problem.spring.web.advice.general.GeneralAdviceTrait; -import org.zalando.problem.spring.web.advice.http.HttpAdviceTrait; import org.zalando.problem.spring.web.advice.io.IOAdviceTrait; import org.zalando.problem.spring.web.advice.network.NetworkAdviceTrait; import org.zalando.problem.spring.web.advice.validation.ValidationAdviceTrait; @@ -22,14 +21,12 @@ * @see AdviceTrait * @see CustomAdviceTrait * @see GeneralAdviceTrait - * @see HttpAdviceTrait * @see IOAdviceTrait * @see ValidationAdviceTrait */ @API(status = STABLE) public interface ProblemHandling extends GeneralAdviceTrait, - HttpAdviceTrait, IOAdviceTrait, NetworkAdviceTrait, ValidationAdviceTrait { diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/HttpAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/HttpAdviceTrait.java deleted file mode 100644 index ff0044b2..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/HttpAdviceTrait.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.zalando.problem.spring.web.advice.http; - -import org.apiguardian.api.API; -import org.zalando.problem.spring.web.advice.AdviceTrait; - -import static org.apiguardian.api.API.Status.STABLE; - -/** - * @see AdviceTrait - */ -@API(status = STABLE) -public interface HttpAdviceTrait { - -} diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/package-info.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/package-info.java deleted file mode 100644 index c3650d44..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/http/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -@ParametersAreNonnullByDefault -package org.zalando.problem.spring.web.advice.http; - -import javax.annotation.ParametersAreNonnullByDefault; - From e2d4858db01bbc36bd808194263b7ccf9db9385c Mon Sep 17 00:00:00 2001 From: drohe Date: Fri, 24 Feb 2023 19:31:24 +0100 Subject: [PATCH 10/12] removed handling of HttpMessageNotReadableException --- .../spring/web/advice/io/IOAdviceTrait.java | 1 - .../io/MessageNotReadableAdviceTrait.java | 30 ------- .../io/MessageNotReadableAdviceTraitTest.java | 82 ------------------- 3 files changed, 113 deletions(-) delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/MessageNotReadableAdviceTrait.java delete mode 100644 problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/io/MessageNotReadableAdviceTraitTest.java diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/IOAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/IOAdviceTrait.java index f7a7f5b5..c521c453 100644 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/IOAdviceTrait.java +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/IOAdviceTrait.java @@ -10,7 +10,6 @@ */ @API(status = STABLE) public interface IOAdviceTrait extends - MessageNotReadableAdviceTrait, MultipartAdviceTrait, TypeMismatchAdviceTrait { } diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/MessageNotReadableAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/MessageNotReadableAdviceTrait.java deleted file mode 100644 index 1161e240..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/MessageNotReadableAdviceTrait.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.zalando.problem.spring.web.advice.io; - -import org.apiguardian.api.API; -import org.springframework.http.ResponseEntity; -import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.context.request.NativeWebRequest; -import org.zalando.problem.Problem; -import org.zalando.problem.Status; -import org.zalando.problem.spring.web.advice.AdviceTrait; - -import static org.apiguardian.api.API.Status.INTERNAL; -import static org.apiguardian.api.API.Status.STABLE; - -/** - * @see HttpMessageNotReadableException - * @see Status#BAD_REQUEST - */ -@API(status = STABLE) -public interface MessageNotReadableAdviceTrait extends AdviceTrait { - - @API(status = INTERNAL) - @ExceptionHandler - default ResponseEntity handleMessageNotReadableException( - final HttpMessageNotReadableException exception, - final NativeWebRequest request) { - return create(Status.BAD_REQUEST, exception, request); - } - -} diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/io/MessageNotReadableAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/io/MessageNotReadableAdviceTraitTest.java deleted file mode 100644 index d3e54253..00000000 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/io/MessageNotReadableAdviceTraitTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.zalando.problem.spring.web.advice.io; - -import org.junit.jupiter.api.Test; -import org.zalando.problem.spring.web.advice.AdviceTraitTesting; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.springframework.http.HttpMethod.PUT; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -final class MessageNotReadableAdviceTraitTest implements AdviceTraitTesting { - - @Test - void missingRequestBody() throws Exception { - mvc().perform(request(PUT, "http://localhost/api/handler-put") - .contentType("application/json")) - .andExpect(status().isBadRequest()) - .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Bad Request"))) - .andExpect(jsonPath("$.status", is(400))) - .andExpect(jsonPath("$.detail", containsString("request body is missing"))); - } - - @Test - void malformedJsonRequestBody() throws Exception { - mvc().perform(request(PUT, "http://localhost/api/json-object") - .contentType("application/json") - .content("{")) - .andExpect(status().isBadRequest()) - .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Bad Request"))) - .andExpect(jsonPath("$.status", is(400))) - .andExpect(jsonPath("$.detail", containsString("Unexpected end-of-input"))); - } - - @Test - void invalidFormat() throws Exception { - mvc().perform(request(PUT, "http://localhost/api/json-decimal") - .contentType("application/json") - .content("\"foobar\"")) - .andExpect(status().isBadRequest()) - .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Bad Request"))) - .andExpect(jsonPath("$.status", is(400))) - .andExpect(jsonPath("$.detail", containsString("java.math.BigDecimal"))) - .andExpect(jsonPath("$.detail", containsString("foobar"))); - } - - @Test - void noConstructor() throws Exception { - mvc().perform(request(PUT, "http://localhost/api/json-user") - .contentType("application/json") - .content("{}")) - .andExpect(status().isBadRequest()) - .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Bad Request"))) - .andExpect(jsonPath("$.status", is(400))) - .andExpect(jsonPath("$.detail", containsString("org.zalando.problem.spring.web.advice.example.User"))); - } - - @Test - void wrongJsonTypeRequestBody() throws Exception { - mvc().perform(request(PUT, "http://localhost/api/json-object") - .contentType("application/json") - .content("[]")) - .andExpect(status().isBadRequest()) - .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Bad Request"))) - .andExpect(jsonPath("$.status", is(400))) - .andExpect(jsonPath("$.detail", containsString("java.util.LinkedHashMap"))) - .andExpect(jsonPath("$.detail", containsString("START_ARRAY"))); - } - -} From cea997b043bf21a65432bae12d9cd004f7039dc0 Mon Sep 17 00:00:00 2001 From: drohe Date: Fri, 24 Feb 2023 19:39:58 +0100 Subject: [PATCH 11/12] removed handling of TypeMismatchException --- .../spring/web/advice/io/IOAdviceTrait.java | 3 +- .../advice/io/TypeMismatchAdviceTrait.java | 29 ------------------- .../advice/io/TypeMistmatchAdviceTrait.java | 11 ------- .../io/TypeMismatchAdviceTraitTest.java | 27 ----------------- 4 files changed, 1 insertion(+), 69 deletions(-) delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/TypeMismatchAdviceTrait.java delete mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/TypeMistmatchAdviceTrait.java delete mode 100644 problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/io/TypeMismatchAdviceTraitTest.java diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/IOAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/IOAdviceTrait.java index c521c453..1afa1470 100644 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/IOAdviceTrait.java +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/IOAdviceTrait.java @@ -10,6 +10,5 @@ */ @API(status = STABLE) public interface IOAdviceTrait extends - MultipartAdviceTrait, - TypeMismatchAdviceTrait { + MultipartAdviceTrait { } diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/TypeMismatchAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/TypeMismatchAdviceTrait.java deleted file mode 100644 index 70adba1c..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/TypeMismatchAdviceTrait.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.zalando.problem.spring.web.advice.io; - -import org.apiguardian.api.API; -import org.springframework.beans.TypeMismatchException; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.context.request.NativeWebRequest; -import org.zalando.problem.Problem; -import org.zalando.problem.Status; -import org.zalando.problem.spring.web.advice.AdviceTrait; - -import static org.apiguardian.api.API.Status.INTERNAL; -import static org.apiguardian.api.API.Status.STABLE; - -/** - * @see TypeMismatchException - * @see Status#BAD_REQUEST - */ -@API(status = STABLE) -public interface TypeMismatchAdviceTrait extends AdviceTrait { - - @API(status = INTERNAL) - @ExceptionHandler - default ResponseEntity handleTypeMismatch( - final TypeMismatchException exception, - final NativeWebRequest request) { - return create(Status.BAD_REQUEST, exception, request); - } -} diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/TypeMistmatchAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/TypeMistmatchAdviceTrait.java deleted file mode 100644 index 2fd0b83a..00000000 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/io/TypeMistmatchAdviceTrait.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.zalando.problem.spring.web.advice.io; - -import org.apiguardian.api.API; - -import static org.apiguardian.api.API.Status.DEPRECATED; - -@API(status = DEPRECATED) -@Deprecated -@SuppressWarnings("SpellCheckingInspection") -public interface TypeMistmatchAdviceTrait extends TypeMismatchAdviceTrait { -} diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/io/TypeMismatchAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/io/TypeMismatchAdviceTraitTest.java deleted file mode 100644 index 5723d193..00000000 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/io/TypeMismatchAdviceTraitTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.zalando.problem.spring.web.advice.io; - -import org.junit.jupiter.api.Test; -import org.zalando.problem.spring.web.advice.AdviceTraitTesting; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.springframework.http.HttpMethod.GET; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.request; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -final class TypeMismatchAdviceTraitTest implements AdviceTraitTesting { - - @Test - void typeMismatch() throws Exception { - mvc().perform(request(GET, "http://localhost/api/handler-conversion?dateTime=abc")) - .andExpect(status().isBadRequest()) - .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) - .andExpect(jsonPath("$.title", is("Bad Request"))) - .andExpect(jsonPath("$.status", is(400))) - .andExpect(jsonPath("$.detail", containsString("Failed to convert"))); - } - -} From 6efb068fbdec211509c3b4e5ba6f06fd3642e1e4 Mon Sep 17 00:00:00 2001 From: drohe Date: Fri, 31 Mar 2023 16:10:00 +0200 Subject: [PATCH 12/12] Spring Problem exception handler with specific improvements --- .../ZalandoProblemExceptionHandler.java | 122 ++++++++++++++++++ .../ConstraintViolationAdviceTrait.java | 11 +- .../spring/web/advice/AdviceTraitTesting.java | 13 +- .../general/ProblemAdviceTraitTest.java | 2 +- .../ResponseStatusAdviceTraitTest.java | 2 +- .../advice/io/MultipartAdviceTraitTest.java | 2 +- .../validation/BindAdviceTraitTest.java | 8 +- ...MethodArgumentNotValidAdviceTraitTest.java | 2 +- 8 files changed, 146 insertions(+), 16 deletions(-) create mode 100644 problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/ZalandoProblemExceptionHandler.java diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/ZalandoProblemExceptionHandler.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/ZalandoProblemExceptionHandler.java new file mode 100644 index 00000000..0e5b8009 --- /dev/null +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/ZalandoProblemExceptionHandler.java @@ -0,0 +1,122 @@ +package org.zalando.problem.spring.web.advice; + +import java.util.List; +import java.util.Map; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ProblemDetail; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.BindException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.multipart.MultipartException; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; +import org.zalando.problem.ThrowableProblem; +import org.zalando.problem.spring.web.advice.validation.ConstraintViolationAdviceTrait; +import org.zalando.problem.spring.web.advice.validation.ValidationAdviceTrait; +import org.zalando.problem.violations.ConstraintViolationProblem; +import org.zalando.problem.violations.Violation; + +import jakarta.validation.ConstraintViolationException; + +/** + * A controller advice that integrates with Spring's Problem JSON support and + * also overwrites functionality where Zalando Problem JSON does better handling + * especially when failing with validation errors. + */ +@ControllerAdvice +public class ZalandoProblemExceptionHandler extends ResponseEntityExceptionHandler { + + private ValidationAdviceTrait validationTrait = new ValidationAdviceTrait() { + }; + + private ConstraintViolationAdviceTrait cveTrait = new ConstraintViolationAdviceTrait() { + }; + + /** + * Overridden to add violations to the problem details. + */ + @Override + protected ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotValidException ex, + HttpHeaders headers, HttpStatusCode status, WebRequest request) { + List violations = validationTrait.createViolations(ex.getBindingResult()); + + ProblemDetail body = ex.getBody(); + body.setType(ConstraintViolationProblem.TYPE); + body.setTitle("Constraint Violation"); + body.setProperty("violations", violations); + + return handleExceptionInternal(ex, body, headers, status, request); + } + + /** + * Overridden to add violations to the problem details. + */ + @Override + @Deprecated(since = "6.0", forRemoval = true) + protected ResponseEntity handleBindException(BindException ex, HttpHeaders headers, HttpStatusCode status, + WebRequest request) { + List violations = validationTrait.createViolations(ex.getBindingResult()); + + ProblemDetail body = ProblemDetail.forStatusAndDetail(status, "Failed to bind request"); + body.setType(ConstraintViolationProblem.TYPE); + body.setTitle("Constraint Violation"); + body.setProperty("violations", violations); + + return handleExceptionInternal(ex, body, headers, status, request); + } + + /** + * Handles Spring's MultipartException. + */ + @ExceptionHandler + public ResponseEntity handleValidationException(MultipartException ex, WebRequest request) + throws Exception { + HttpStatus status = HttpStatus.BAD_REQUEST; + + ProblemDetail body = ProblemDetail.forStatusAndDetail(status, "Current request is not a multipart request"); + + return handleExceptionInternal(ex, body, HttpHeaders.EMPTY, status, request); + } + + /** + * Handles Jakarta ConstraintViolationExceptions thrown within the application code and not within the Spring Framework. + */ + @ExceptionHandler + public ResponseEntity handleValidationException(ConstraintViolationException ex, WebRequest request) + throws Exception { + List violations = cveTrait.createViolations(ex.getConstraintViolations()); + + ProblemDetail body = ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, "Invalid request content."); + body.setType(ConstraintViolationProblem.TYPE); + body.setTitle("Constraint Violation"); + body.setProperty("violations", violations); + + return handleExceptionInternal(ex, body, HttpHeaders.EMPTY, HttpStatus.BAD_REQUEST, request); + } + + /** + * Handles ThrowableProblem exceptions to map them to Spring Problem JSON support. + */ + @ExceptionHandler + public ResponseEntity handleThrowableProblemException(ThrowableProblem ex, WebRequest request) + throws Exception { + HttpStatus status = HttpStatus.valueOf(ex.getStatus().getStatusCode()); + + ProblemDetail body = ProblemDetail.forStatusAndDetail(status, ex.getDetail()); + body.setType(ex.getType()); + body.setTitle(ex.getTitle()); + body.setInstance(ex.getInstance()); + for (Map.Entry entry : ex.getParameters().entrySet()) { + body.setProperty(entry.getKey(), entry.getValue()); + } + + return handleExceptionInternal(ex, body, HttpHeaders.EMPTY, status, request); + } + + +} \ No newline at end of file diff --git a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/validation/ConstraintViolationAdviceTrait.java b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/validation/ConstraintViolationAdviceTrait.java index c866d374..30fc97eb 100644 --- a/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/validation/ConstraintViolationAdviceTrait.java +++ b/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/validation/ConstraintViolationAdviceTrait.java @@ -11,6 +11,7 @@ import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import java.util.List; +import java.util.Set; import static java.util.stream.Collectors.toList; import static org.apiguardian.api.API.Status.INTERNAL; @@ -32,14 +33,16 @@ default ResponseEntity handleConstraintViolation( final ConstraintViolationException exception, final NativeWebRequest request) { - final List violations = exception.getConstraintViolations().stream() - .map(this::createViolation) - .collect(toList()); + final List violations = createViolations(exception.getConstraintViolations()); return newConstraintViolationProblem(exception, violations, request); } - default Violation createViolation(final ConstraintViolation violation) { + default List createViolations(Set> violations) { + return violations.stream().map(this::createViolation).collect(toList()); + } + + default Violation createViolation(final ConstraintViolation violation) { return new Violation(formatFieldName(violation.getPropertyPath().toString()), violation.getMessage()); } diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/AdviceTraitTesting.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/AdviceTraitTesting.java index 1e01d6ca..27a637bc 100644 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/AdviceTraitTesting.java +++ b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/AdviceTraitTesting.java @@ -2,7 +2,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.http.converter.ByteArrayHttpMessageConverter; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.converter.json.ProblemDetailJacksonMixin; import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @@ -14,6 +16,8 @@ import static java.util.Collections.singletonList; import static org.springframework.http.MediaType.APPLICATION_JSON; +import org.springframework.http.ProblemDetail; + public interface AdviceTraitTesting { default ProblemHandling unit() { @@ -25,9 +29,10 @@ default MockMvc mvc() { return MockMvcBuilders .standaloneSetup(new ExampleRestController()) - .setContentNegotiationManager(new ContentNegotiationManager(singletonList( - new FixedContentNegotiationStrategy(APPLICATION_JSON)))) - .setControllerAdvice(unit()) + //.setContentNegotiationManager(new ContentNegotiationManager(singletonList( + // new FixedContentNegotiationStrategy(APPLICATION_JSON)))) + //.setControllerAdvice(unit()) + .setControllerAdvice(new ZalandoProblemExceptionHandler()) .setMessageConverters( new MappingJackson2HttpMessageConverter(mapper), new MappingJackson2XmlHttpMessageConverter(), @@ -36,7 +41,7 @@ default MockMvc mvc() { } default ObjectMapper mapper() { - return new ObjectMapper().registerModule(new ProblemModule()); + return Jackson2ObjectMapperBuilder.json().build(); } } diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/general/ProblemAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/general/ProblemAdviceTraitTest.java index cda8b849..555fc2de 100644 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/general/ProblemAdviceTraitTest.java +++ b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/general/ProblemAdviceTraitTest.java @@ -17,7 +17,7 @@ void throwableProblem() throws Exception { mvc().perform(request(GET, "http://localhost/api/handler-problem")) .andExpect(status().isConflict()) .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) + .andExpect(jsonPath("$.type", is("about:blank"))) .andExpect(jsonPath("$.title", is("Expected"))) .andExpect(jsonPath("$.status", is(409))) .andExpect(jsonPath("$.detail", is("Nothing out of the ordinary"))); diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/general/ResponseStatusAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/general/ResponseStatusAdviceTraitTest.java index 3d0dfc6f..2fc44b11 100644 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/general/ResponseStatusAdviceTraitTest.java +++ b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/general/ResponseStatusAdviceTraitTest.java @@ -17,7 +17,7 @@ void throwableProblem() throws Exception { mvc().perform(request(GET, "http://localhost/api/handler-throwable-extended")) .andExpect(status().isNotImplemented()) .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) + .andExpect(jsonPath("$.type", is("about:blank"))) .andExpect(jsonPath("$.title", is("Not Implemented"))) .andExpect(jsonPath("$.status", is(501))); } diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/io/MultipartAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/io/MultipartAdviceTraitTest.java index bbb63a83..88117df2 100644 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/io/MultipartAdviceTraitTest.java +++ b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/io/MultipartAdviceTraitTest.java @@ -18,7 +18,7 @@ void multipart() throws Exception { mvc().perform(request(POST, "http://localhost/api/handler-multipart")) .andExpect(status().isBadRequest()) .andExpect(header().string("Content-Type", is("application/problem+json"))) - .andExpect(jsonPath("$.type").doesNotExist()) + .andExpect(jsonPath("$.type", is("about:blank"))) .andExpect(jsonPath("$.title", is("Bad Request"))) .andExpect(jsonPath("$.status", is(400))) .andExpect(jsonPath("$.detail", containsString("not a multipart request"))); diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/validation/BindAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/validation/BindAdviceTraitTest.java index 04731a75..7595fa3b 100644 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/validation/BindAdviceTraitTest.java +++ b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/validation/BindAdviceTraitTest.java @@ -22,10 +22,10 @@ void invalidRequestQueryParams() throws Exception { .andExpect(jsonPath("$.title", is("Constraint Violation"))) .andExpect(jsonPath("$.status", is(400))) .andExpect(jsonPath("$.violations", hasSize(2))) - .andExpect(jsonPath("$.violations[0].field", is("page"))) - .andExpect(jsonPath("$.violations[0].message", is("must be greater than or equal to 0"))) - .andExpect(jsonPath("$.violations[1].field", is("size"))) - .andExpect(jsonPath("$.violations[1].message", is("must be greater than or equal to 1"))); + .andExpect(jsonPath("$.violations[1].field", is("page"))) + .andExpect(jsonPath("$.violations[1].message", is("must be greater than or equal to 0"))) + .andExpect(jsonPath("$.violations[0].field", is("size"))) + .andExpect(jsonPath("$.violations[0].message", is("must be greater than or equal to 1"))); } } diff --git a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/validation/MethodArgumentNotValidAdviceTraitTest.java b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/validation/MethodArgumentNotValidAdviceTraitTest.java index 487fdbff..b121bdd7 100644 --- a/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/validation/MethodArgumentNotValidAdviceTraitTest.java +++ b/problem-spring-web/src/test/java/org/zalando/problem/spring/web/advice/validation/MethodArgumentNotValidAdviceTraitTest.java @@ -40,7 +40,7 @@ void invalidRequestBody() throws Exception { .andExpect(jsonPath("$.title", is("Constraint Violation"))) .andExpect(jsonPath("$.status", is(400))) .andExpect(jsonPath("$.violations", hasSize(1))) - .andExpect(jsonPath("$.violations[0].field", is("user_request"))) + .andExpect(jsonPath("$.violations[0].field", is("userRequest"))) .andExpect(jsonPath("$.violations[0].message", is("must not be called Bob"))); }