Missing path variable is now a 500 error
Before this change a missing path variable value resulted in a 400 error where in fact the error is due to a mismatch between the declared @PathVariable and the URI template, i.e. a 500 error. This change introduced a MissingPathVariableException as a sub-class of ServletRequestBindingException (the exception previously thrown) and results in a response status code of 500 by default. Issue: SPR-13121
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.web.servlet.mvc.method.annotation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -26,15 +28,13 @@ import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
import org.springframework.web.bind.ServletRequestBindingException;
|
||||
import org.springframework.web.bind.MissingPathVariableException;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.View;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Test fixture with {@link PathVariableMethodArgumentResolver}.
|
||||
*
|
||||
@@ -96,7 +96,7 @@ public class PathVariableMethodArgumentResolverTests {
|
||||
uriTemplateVars.put("name", "value");
|
||||
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
|
||||
|
||||
Map<String, Object> pathVars = new HashMap<String, Object>();
|
||||
Map<String, Object> pathVars;
|
||||
uriTemplateVars.put("oldName", "oldValue");
|
||||
request.setAttribute(View.PATH_VARIABLES, uriTemplateVars);
|
||||
|
||||
@@ -110,12 +110,13 @@ public class PathVariableMethodArgumentResolverTests {
|
||||
assertEquals("oldValue", pathVars.get("oldName"));
|
||||
}
|
||||
|
||||
@Test(expected = ServletRequestBindingException.class)
|
||||
@Test(expected = MissingPathVariableException.class)
|
||||
public void handleMissingValue() throws Exception {
|
||||
resolver.resolveArgument(paramNamedString, mavContainer, webRequest, null);
|
||||
fail("Unresolved path variable should lead to exception.");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void handle(@PathVariable(value = "name") String param1, String param2) {
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.ConversionNotSupportedException;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -41,6 +42,7 @@ import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.MissingPathVariableException;
|
||||
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||
import org.springframework.web.bind.ServletRequestBindingException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
@@ -86,15 +88,16 @@ public class ResponseEntityExceptionHandlerTests {
|
||||
@Test
|
||||
public void supportsAllDefaultHandlerExceptionResolverExceptionTypes() throws Exception {
|
||||
|
||||
Method annotMethod = ResponseEntityExceptionHandler.class.getMethod("handleException", Exception.class, WebRequest.class);
|
||||
ExceptionHandler annot = annotMethod.getAnnotation(ExceptionHandler.class);
|
||||
List<Class<? extends Throwable>> supportedTypes = Arrays.asList(annot.value());
|
||||
Class<ResponseEntityExceptionHandler> clazz = ResponseEntityExceptionHandler.class;
|
||||
Method handleExceptionMethod = clazz.getMethod("handleException", Exception.class, WebRequest.class);
|
||||
ExceptionHandler annotation = handleExceptionMethod.getAnnotation(ExceptionHandler.class);
|
||||
List<Class<?>> exceptionTypes = Arrays.asList(annotation.value());
|
||||
|
||||
for (Method method : DefaultHandlerExceptionResolver.class.getDeclaredMethods()) {
|
||||
Class<?>[] paramTypes = method.getParameterTypes();
|
||||
if (method.getName().startsWith("handle") && (paramTypes.length == 4)) {
|
||||
String name = paramTypes[0].getSimpleName();
|
||||
assertTrue("@ExceptionHandler is missing " + name, supportedTypes.contains(paramTypes[0]));
|
||||
assertTrue("@ExceptionHandler is missing " + name, exceptionTypes.contains(paramTypes[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,6 +133,14 @@ public class ResponseEntityExceptionHandlerTests {
|
||||
testException(ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingPathVariable() throws NoSuchMethodException {
|
||||
Method method = getClass().getDeclaredMethod("handle", String.class);
|
||||
MethodParameter parameter = new MethodParameter(method, 0);
|
||||
Exception ex = new MissingPathVariableException("param", parameter);
|
||||
testException(ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingServletRequestParameter() {
|
||||
Exception ex = new MissingServletRequestParameterException("param", "type");
|
||||
@@ -241,8 +252,10 @@ public class ResponseEntityExceptionHandlerTests {
|
||||
headers.set("someHeader", "someHeaderValue");
|
||||
return handleExceptionInternal(ex, "error content", headers, status, request);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
void handle(String arg) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.web.servlet.mvc.support;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -36,6 +37,7 @@ import org.springframework.validation.BindException;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.MissingPathVariableException;
|
||||
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||
import org.springframework.web.bind.ServletRequestBindingException;
|
||||
import org.springframework.web.multipart.support.MissingServletRequestPartException;
|
||||
@@ -93,6 +95,19 @@ public class DefaultHandlerExceptionResolverTests {
|
||||
assertEquals("Invalid Accept header", "application/pdf", response.getHeader("Accept"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMissingPathVariable() throws NoSuchMethodException {
|
||||
Method method = getClass().getMethod("handle", String.class);
|
||||
MethodParameter parameter = new MethodParameter(method, 0);
|
||||
MissingPathVariableException ex = new MissingPathVariableException("foo", parameter);
|
||||
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
|
||||
assertNotNull("No ModelAndView returned", mav);
|
||||
assertTrue("No Empty ModelAndView returned", mav.isEmpty());
|
||||
assertEquals("Invalid status code", 500, response.getStatus());
|
||||
assertEquals("Missing URI template variable 'foo' for method parameter of type String",
|
||||
response.getErrorMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMissingServletRequestParameter() {
|
||||
MissingServletRequestParameterException ex = new MissingServletRequestParameterException("foo", "bar");
|
||||
@@ -196,6 +211,7 @@ public class DefaultHandlerExceptionResolverTests {
|
||||
assertSame(ex, request.getAttribute("javax.servlet.error.exception"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void handle(String arg) {
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user