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-2014 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.
|
||||
@@ -25,6 +25,7 @@ import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.MissingPathVariableException;
|
||||
import org.springframework.web.bind.ServletRequestBindingException;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@@ -101,9 +102,10 @@ public class PathVariableMethodArgumentResolver extends AbstractNamedValueMethod
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleMissingValue(String name, MethodParameter parameter) throws ServletRequestBindingException {
|
||||
throw new ServletRequestBindingException("Missing URI template variable '" + name +
|
||||
"' for method parameter of type " + parameter.getParameterType().getSimpleName());
|
||||
protected void handleMissingValue(String name, MethodParameter parameter)
|
||||
throws ServletRequestBindingException {
|
||||
|
||||
throw new MissingPathVariableException(name, parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -37,6 +37,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;
|
||||
@@ -96,6 +97,7 @@ public abstract class ResponseEntityExceptionHandler {
|
||||
HttpRequestMethodNotSupportedException.class,
|
||||
HttpMediaTypeNotSupportedException.class,
|
||||
HttpMediaTypeNotAcceptableException.class,
|
||||
MissingPathVariableException.class,
|
||||
MissingServletRequestParameterException.class,
|
||||
ServletRequestBindingException.class,
|
||||
ConversionNotSupportedException.class,
|
||||
@@ -127,6 +129,10 @@ public abstract class ResponseEntityExceptionHandler {
|
||||
HttpStatus status = HttpStatus.NOT_ACCEPTABLE;
|
||||
return handleHttpMediaTypeNotAcceptable((HttpMediaTypeNotAcceptableException) ex, headers, status, request);
|
||||
}
|
||||
else if (ex instanceof MissingPathVariableException) {
|
||||
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
return handleMissingPathVariable((MissingPathVariableException) ex, headers, status, request);
|
||||
}
|
||||
else if (ex instanceof MissingServletRequestParameterException) {
|
||||
HttpStatus status = HttpStatus.BAD_REQUEST;
|
||||
return handleMissingServletRequestParameter((MissingServletRequestParameterException) ex, headers, status, request);
|
||||
@@ -270,6 +276,22 @@ public abstract class ResponseEntityExceptionHandler {
|
||||
return handleExceptionInternal(ex, null, headers, status, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize the response for MissingPathVariableException.
|
||||
* This method delegates to {@link #handleExceptionInternal(Exception, Object, HttpHeaders, HttpStatus, WebRequest)}.
|
||||
* @param ex the exception
|
||||
* @param headers the headers to be written to the response
|
||||
* @param status the selected response status
|
||||
* @param request the current request
|
||||
* @return a {@code ResponseEntity} instance
|
||||
* @since 4.2
|
||||
*/
|
||||
protected ResponseEntity<Object> handleMissingPathVariable(MissingPathVariableException ex,
|
||||
HttpHeaders headers, HttpStatus status, WebRequest request) {
|
||||
|
||||
return handleExceptionInternal(ex, null, headers, status, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize the response for MissingServletRequestParameterException.
|
||||
* This method delegates to {@link #handleExceptionInternal(Exception, Object, HttpHeaders, HttpStatus, WebRequest)}.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -38,6 +38,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.ModelAttribute;
|
||||
@@ -119,6 +120,10 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes
|
||||
return handleHttpMediaTypeNotAcceptable((HttpMediaTypeNotAcceptableException) ex, request, response,
|
||||
handler);
|
||||
}
|
||||
else if (ex instanceof MissingPathVariableException) {
|
||||
return handleMissingPathVariable((MissingPathVariableException) ex, request,
|
||||
response, handler);
|
||||
}
|
||||
else if (ex instanceof MissingServletRequestParameterException) {
|
||||
return handleMissingServletRequestParameter((MissingServletRequestParameterException) ex, request,
|
||||
response, handler);
|
||||
@@ -247,6 +252,26 @@ public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionRes
|
||||
return new ModelAndView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the case when a declared path variable does not match any extracted URI variable.
|
||||
* <p>The default implementation sends an HTTP 500 error, and returns an empty {@code ModelAndView}.
|
||||
* Alternatively, a fallback view could be chosen, or the MissingPathVariableException
|
||||
* could be rethrown as-is.
|
||||
* @param ex the MissingPathVariableException to be handled
|
||||
* @param request current HTTP request
|
||||
* @param response current HTTP response
|
||||
* @param handler the executed handler
|
||||
* @return an empty ModelAndView indicating the exception was handled
|
||||
* @throws IOException potentially thrown from response.sendError()
|
||||
* @since 4.2
|
||||
*/
|
||||
protected ModelAndView handleMissingPathVariable(MissingPathVariableException ex,
|
||||
HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
|
||||
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex.getMessage());
|
||||
return new ModelAndView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the case when a required parameter is missing.
|
||||
* <p>The default implementation sends an HTTP 400 error, and returns an empty {@code ModelAndView}.
|
||||
|
||||
Reference in New Issue
Block a user