Raise and handle NoResourceFoundException

See gh-29491
This commit is contained in:
rstoyanchev
2023-06-19 16:22:34 +01:00
parent 83b0f4f394
commit c00508d6cf
8 changed files with 195 additions and 43 deletions

View File

@@ -114,6 +114,7 @@ import org.springframework.web.servlet.resource.CssLinkResourceTransformer;
import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
import org.springframework.web.servlet.resource.EncodedResourceResolver;
import org.springframework.web.servlet.resource.FixedVersionStrategy;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import org.springframework.web.servlet.resource.PathResourceResolver;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import org.springframework.web.servlet.resource.ResourceResolver;
@@ -147,6 +148,7 @@ import org.springframework.web.util.UrlPathHelper;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.InstanceOfAssertFactories.BOOLEAN;
/**
@@ -417,8 +419,8 @@ public class MvcNamespaceTests {
for (HandlerInterceptor interceptor : chain.getInterceptorList()) {
interceptor.preHandle(request, response, chain.getHandler());
}
ModelAndView mv = adapter.handle(request, response, chain.getHandler());
assertThat((Object) mv).isNull();
assertThatThrownBy(() -> adapter.handle(request, response, chain.getHandler()))
.isInstanceOf(NoResourceFoundException.class);
}
@Test

View File

@@ -63,6 +63,7 @@ import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
import org.springframework.web.testfixture.servlet.MockHttpServletResponse;
import org.springframework.web.testfixture.servlet.MockServletConfig;
@@ -265,6 +266,11 @@ public class ResponseEntityExceptionHandlerTests {
assertThat(responseEntity.getHeaders()).isEmpty();
}
@Test
public void noResourceFoundException() {
testException(new NoResourceFoundException(HttpMethod.GET, "/resource"));
}
@Test
public void asyncRequestTimeoutException() {
testException(new AsyncRequestTimeoutException());

View File

@@ -48,6 +48,7 @@ import org.springframework.web.multipart.support.MissingServletRequestPartExcept
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
import org.springframework.web.testfixture.servlet.MockHttpServletResponse;
@@ -182,7 +183,7 @@ public class DefaultHandlerExceptionResolverTests {
}
@Test
public void handleMissingServletRequestPartException() throws Exception {
public void handleMissingServletRequestPartException() {
MissingServletRequestPartException ex = new MissingServletRequestPartException("name");
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
assertThat(mav).as("No ModelAndView returned").isNotNull();
@@ -194,7 +195,7 @@ public class DefaultHandlerExceptionResolverTests {
}
@Test
public void handleBindException() throws Exception {
public void handleBindException() {
BindException ex = new BindException(new Object(), "name");
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
assertThat(mav).as("No ModelAndView returned").isNotNull();
@@ -203,7 +204,7 @@ public class DefaultHandlerExceptionResolverTests {
}
@Test
public void handleNoHandlerFoundException() throws Exception {
public void handleNoHandlerFoundException() {
ServletServerHttpRequest req = new ServletServerHttpRequest(
new MockHttpServletRequest("GET","/resource"));
NoHandlerFoundException ex = new NoHandlerFoundException(req.getMethod().name(),
@@ -215,7 +216,16 @@ public class DefaultHandlerExceptionResolverTests {
}
@Test
public void handleConversionNotSupportedException() throws Exception {
public void handleNoResourceFoundException() {
NoResourceFoundException ex = new NoResourceFoundException(HttpMethod.GET, "/resource");
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
assertThat(mav).as("No ModelAndView returned").isNotNull();
assertThat(mav.isEmpty()).as("No Empty ModelAndView returned").isTrue();
assertThat(response.getStatus()).as("Invalid status code").isEqualTo(404);
}
@Test
public void handleConversionNotSupportedException() {
ConversionNotSupportedException ex =
new ConversionNotSupportedException(new Object(), String.class, new Exception());
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
@@ -228,7 +238,7 @@ public class DefaultHandlerExceptionResolverTests {
}
@Test // SPR-14669
public void handleAsyncRequestTimeoutException() throws Exception {
public void handleAsyncRequestTimeoutException() {
Exception ex = new AsyncRequestTimeoutException();
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
assertThat(mav).as("No ModelAndView returned").isNotNull();

View File

@@ -29,7 +29,6 @@ import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.HttpRequestMethodNotSupportedException;
@@ -44,6 +43,7 @@ import org.springframework.web.testfixture.servlet.MockServletContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
@@ -367,11 +367,11 @@ class ResourceHttpRequestHandlerTests {
testInvalidPath("%2F%2F%2E%2E%2F%2F%2E%2E" + secretPath, handler);
}
private void testInvalidPath(String requestPath, ResourceHttpRequestHandler handler) throws Exception {
private void testInvalidPath(String requestPath, ResourceHttpRequestHandler handler) {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, requestPath);
this.response = new MockHttpServletResponse();
handler.handleRequest(this.request, this.response);
assertThat(this.response.getStatus()).isEqualTo(HttpStatus.NOT_FOUND.value());
assertThatThrownBy(() -> handler.handleRequest(this.request, this.response))
.isInstanceOf(NoResourceFoundException.class);
}
@Test
@@ -409,19 +409,17 @@ class ResourceHttpRequestHandlerTests {
testResolvePathWithTraversal(location, "/ " + secretPath);
}
private void testResolvePathWithTraversal(Resource location, String requestPath) throws Exception {
private void testResolvePathWithTraversal(Resource location, String requestPath) {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, requestPath);
this.response = new MockHttpServletResponse();
this.handler.handleRequest(this.request, this.response);
assertThat(this.response.getStatus()).isEqualTo(HttpStatus.NOT_FOUND.value());
assertNotFound();
}
@Test
void ignoreInvalidEscapeSequence() throws Exception {
void ignoreInvalidEscapeSequence() {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/%foo%/bar.txt");
this.response = new MockHttpServletResponse();
this.handler.handleRequest(this.request, this.response);
assertThat(this.response.getStatus()).isEqualTo(404);
assertNotFound();
}
@Test
@@ -506,32 +504,29 @@ class ResourceHttpRequestHandlerTests {
@Test
void directory() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "js/");
this.handler.handleRequest(this.request, this.response);
assertThat(this.response.getStatus()).isEqualTo(404);
assertNotFound();
}
@Test
void directoryInJarFile() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "underscorejs/");
this.handler.handleRequest(this.request, this.response);
assertThat(this.response.getStatus()).isEqualTo(404);
assertNotFound();
}
@Test
void missingResourcePath() throws Exception {
void missingResourcePath() {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "");
this.handler.handleRequest(this.request, this.response);
assertThat(this.response.getStatus()).isEqualTo(404);
assertNotFound();
}
@Test
void noPathWithinHandlerMappingAttribute() throws Exception {
void noPathWithinHandlerMappingAttribute() {
assertThatIllegalStateException().isThrownBy(() ->
this.handler.handleRequest(this.request, this.response));
}
@Test
void unsupportedHttpMethod() throws Exception {
void unsupportedHttpMethod() {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
this.request.setMethod("POST");
assertThatExceptionOfType(HttpRequestMethodNotSupportedException.class).isThrownBy(() ->
@@ -539,19 +534,18 @@ class ResourceHttpRequestHandlerTests {
}
@Test
void resourceNotFound() throws Exception {
void testResourceNotFound() {
for (HttpMethod method : HttpMethod.values()) {
this.request = new MockHttpServletRequest("GET", "");
this.response = new MockHttpServletResponse();
resourceNotFound(method);
testResourceNotFound(method);
}
}
private void resourceNotFound(HttpMethod httpMethod) throws Exception {
private void testResourceNotFound(HttpMethod httpMethod) {
this.request.setMethod(httpMethod.name());
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "not-there.css");
this.handler.handleRequest(this.request, this.response);
assertThat(this.response.getStatus()).isEqualTo(HttpStatus.NOT_FOUND.value());
assertNotFound();
}
@Test
@@ -756,6 +750,11 @@ class ResourceHttpRequestHandlerTests {
}
private void assertNotFound() {
assertThatThrownBy(() -> this.handler.handleRequest(this.request, this.response))
.isInstanceOf(NoResourceFoundException.class);
}
private long resourceLastModified(String resourceName) throws IOException {
return new ClassPathResource(resourceName, getClass()).getFile().lastModified();
}