diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyEmbeddedErrorHandler.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyEmbeddedErrorHandler.java index d46a4a40e528..170f4680fdae 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyEmbeddedErrorHandler.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyEmbeddedErrorHandler.java @@ -18,20 +18,15 @@ import java.io.IOException; -import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.handler.ErrorHandler; -import org.eclipse.jetty.server.handler.ErrorHandler.ErrorPageMapper; - -import org.springframework.util.ReflectionUtils; +import org.eclipse.jetty.servlet.ErrorPageErrorHandler; /** - * Variation of Jetty's {@link ErrorHandler} that supports all {@link HttpMethod + * Variation of Jetty's {@link ErrorPageErrorHandler} that supports all {@link HttpMethod * HttpMethods} rather than just {@code GET}, {@code POST} and {@code HEAD}. By default * Jetty intentionally only * supports a limited set of HTTP methods for error pages, however, Spring Boot @@ -40,65 +35,18 @@ * @author Phillip Webb * @author Christoph Dreis */ -class JettyEmbeddedErrorHandler extends ErrorHandler implements ErrorPageMapper { - - static final boolean ERROR_PAGE_FOR_METHOD_AVAILABLE; - - static { - ERROR_PAGE_FOR_METHOD_AVAILABLE = ReflectionUtils.findMethod(ErrorHandler.class, "errorPageForMethod", - String.class) != null; - } - - private final ErrorHandler delegate; - - JettyEmbeddedErrorHandler(ErrorHandler delegate) { - this.delegate = delegate; - } +class JettyEmbeddedErrorHandler extends ErrorPageErrorHandler { @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) - throws IOException { - if (!ERROR_PAGE_FOR_METHOD_AVAILABLE) { - String method = request.getMethod(); - if (!HttpMethod.GET.is(method) && !HttpMethod.POST.is(method) && !HttpMethod.HEAD.is(method)) { - request = new ErrorHttpServletRequest(request); - } - } - this.delegate.handle(target, baseRequest, request, response); - } - - @Override - public boolean errorPageForMethod(String method) { // Available in Jetty 9.4.21+ + public boolean errorPageForMethod(String method) { return true; } @Override - public String getErrorPage(HttpServletRequest request) { - if (this.delegate instanceof ErrorPageMapper) { - return ((ErrorPageMapper) this.delegate).getErrorPage(request); - } - return null; - } - - private static class ErrorHttpServletRequest extends HttpServletRequestWrapper { - - private boolean simulateGetMethod = true; - - ErrorHttpServletRequest(HttpServletRequest request) { - super(request); - } - - @Override - public String getMethod() { - return (this.simulateGetMethod ? HttpMethod.GET.toString() : super.getMethod()); - } - - @Override - public ServletContext getServletContext() { - this.simulateGetMethod = false; - return super.getServletContext(); - } - + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) + throws IOException { + baseRequest.setMethod("GET"); + super.doError(target, baseRequest, request, response); } } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java index 8876432d367e..63445ec0d219 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java @@ -342,8 +342,8 @@ private Configuration getErrorPageConfiguration() { @Override public void configure(WebAppContext context) throws Exception { - ErrorHandler errorHandler = context.getErrorHandler(); - context.setErrorHandler(new JettyEmbeddedErrorHandler(errorHandler)); + JettyEmbeddedErrorHandler errorHandler = new JettyEmbeddedErrorHandler(); + context.setErrorHandler(errorHandler); addJettyErrorPages(errorHandler, getErrorPages()); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServlet9419WebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServlet9419WebServerFactoryTests.java index 5a2e1741f614..1683e845afea 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServlet9419WebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServlet9419WebServerFactoryTests.java @@ -16,6 +16,7 @@ package org.springframework.boot.web.embedded.jetty; +import org.eclipse.jetty.server.handler.ErrorHandler; import org.junit.jupiter.api.Test; import org.springframework.boot.testsupport.classpath.ClassPathExclusions; @@ -36,7 +37,7 @@ class JettyServlet9419WebServerFactoryTests extends AbstractJettyServletWebServe @Test void correctVersionOfJettyUsed() { - assertThat(JettyEmbeddedErrorHandler.ERROR_PAGE_FOR_METHOD_AVAILABLE).isFalse(); + assertThat(ErrorHandler.class.getPackage().getImplementationVersion()).isEqualTo("9.4.19.v20190610"); } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactoryTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactoryTests.java index 107f0e8feb3b..26708b4a9ae2 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactoryTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactoryTests.java @@ -21,6 +21,8 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; @@ -30,6 +32,7 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.SslConnectionFactory; +import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.HandlerWrapper; import org.eclipse.jetty.util.thread.QueuedThreadPool; @@ -60,7 +63,10 @@ class JettyServletWebServerFactoryTests extends AbstractJettyServletWebServerFac @Test void correctVersionOfJettyUsed() { - assertThat(JettyEmbeddedErrorHandler.ERROR_PAGE_FOR_METHOD_AVAILABLE).isTrue(); + String jettyVersion = ErrorHandler.class.getPackage().getImplementationVersion(); + Matcher matcher = Pattern.compile("[0-9]+.[0-9]+.([0-9]+)[\\.-].*").matcher(jettyVersion); + assertThat(matcher.find()).isTrue(); + assertThat(Integer.valueOf(matcher.group(1))).isGreaterThan(19); } @Test