Rework JettyEmbeddedErrorHandler to support Jetty 8

Closes gh-10175
pull/10226/merge
Andy Wilkinson 7 years ago
parent 301eedfbe6
commit beb257f452

@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,9 @@
package org.springframework.boot.context.embedded.jetty;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
@ -35,9 +38,20 @@ import org.eclipse.jetty.server.handler.ErrorHandler;
* prefers Tomcat, Jetty and Undertow to all behave in the same way.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
class JettyEmbeddedErrorHandler extends ErrorHandler {
private static final Set<String> SUPPORTED_METHODS;
static {
Set<String> supportedMethods = new HashSet<String>();
supportedMethods.add("GET");
supportedMethods.add("HEAD");
supportedMethods.add("POST");
SUPPORTED_METHODS = Collections.unmodifiableSet(supportedMethods);
}
private final ErrorHandler delegate;
JettyEmbeddedErrorHandler(ErrorHandler delegate) {
@ -47,14 +61,21 @@ class JettyEmbeddedErrorHandler extends ErrorHandler {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request,
HttpServletResponse response) throws IOException {
String method = request.getMethod();
if (!HttpMethod.GET.is(method) && !HttpMethod.POST.is(method)
&& !HttpMethod.HEAD.is(method)) {
if (!isSupported(request.getMethod())) {
request = new ErrorHttpServletRequest(request);
}
this.delegate.handle(target, baseRequest, request, response);
}
private boolean isSupported(String method) {
for (String supportedMethod : SUPPORTED_METHODS) {
if (supportedMethod.equalsIgnoreCase(method)) {
return true;
}
}
return false;
}
private static class ErrorHttpServletRequest extends HttpServletRequestWrapper {
private boolean simulateGetMethod = true;

@ -0,0 +1,112 @@
/*
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.context.embedded.jetty;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.junit.runner.classpath.ClassPathExclusions;
import org.springframework.boot.junit.runner.classpath.ClassPathOverrides;
import org.springframework.boot.junit.runner.classpath.ModifiedClassPathRunner;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link JettyEmbeddedServletContainerFactory} with Jetty 8.
*
* @author Andy Wilkinson
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({ "jetty-*.jar", "tomcat-embed-jasper-*.jar" })
@ClassPathOverrides({ "org.eclipse.jetty:jetty-servlets:8.1.15.v20140411",
"org.eclipse.jetty:jetty-webapp:8.1.15.v20140411" })
public class Jetty8JettyEmbeddedServletContainerFactoryTests {
@Test
public void errorHandling() {
JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory(
0);
factory.addErrorPages(new ErrorPage("/error"));
EmbeddedServletContainer jetty = factory
.getEmbeddedServletContainer(new ServletContextInitializer() {
@Override
public void onStartup(ServletContext servletContext)
throws ServletException {
servletContext.addServlet("test", new TestServlet())
.addMapping("/test");
servletContext.addServlet("error", new ErrorPageServlet())
.addMapping("/error");
}
});
jetty.start();
int port = jetty.getPort();
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new ResponseErrorHandler() {
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
return false;
}
@Override
public void handleError(ClientHttpResponse response) throws IOException {
}
});
ResponseEntity<String> response = restTemplate
.getForEntity("http://localhost:" + port, String.class);
assertThat(response.getBody()).isEqualTo("An error occurred");
}
private static final class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
throw new RuntimeException("boom");
}
}
private static final class ErrorPageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.getWriter().print("An error occurred");
resp.flushBuffer();
}
}
}
Loading…
Cancel
Save