Skip to content

Commit 72013f9

Browse files
committed
Raise exception on missing request parameters
Issue: SPR-10193
1 parent 3a6e7b8 commit 72013f9

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,14 +26,18 @@
2626
import javax.servlet.http.HttpServletRequest;
2727

2828
import org.springframework.http.MediaType;
29+
import org.springframework.util.CollectionUtils;
2930
import org.springframework.util.StringUtils;
3031
import org.springframework.web.HttpMediaTypeNotAcceptableException;
3132
import org.springframework.web.HttpMediaTypeNotSupportedException;
3233
import org.springframework.web.HttpRequestMethodNotSupportedException;
34+
import org.springframework.web.bind.UnsatisfiedServletRequestParameterException;
3335
import org.springframework.web.bind.annotation.RequestMethod;
3436
import org.springframework.web.method.HandlerMethod;
3537
import org.springframework.web.servlet.HandlerMapping;
3638
import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
39+
import org.springframework.web.servlet.mvc.condition.NameValueExpression;
40+
import org.springframework.web.servlet.mvc.condition.ParamsRequestCondition;
3741

3842
/**
3943
* Abstract base class for classes for which {@link RequestMappingInfo} defines
@@ -141,14 +145,17 @@ else if (patternAndMethodMatches.isEmpty() && !allowedMethods.isEmpty()) {
141145

142146
Set<MediaType> consumableMediaTypes;
143147
Set<MediaType> producibleMediaTypes;
148+
Set<String> paramConditions;
144149

145150
if (patternAndMethodMatches.isEmpty()) {
146151
consumableMediaTypes = getConsumableMediaTypes(request, patternMatches);
147152
producibleMediaTypes = getProdicubleMediaTypes(request, patternMatches);
153+
paramConditions = getRequestParams(request, patternMatches);
148154
}
149155
else {
150156
consumableMediaTypes = getConsumableMediaTypes(request, patternAndMethodMatches);
151157
producibleMediaTypes = getProdicubleMediaTypes(request, patternAndMethodMatches);
158+
paramConditions = getRequestParams(request, patternAndMethodMatches);
152159
}
153160

154161
if (!consumableMediaTypes.isEmpty()) {
@@ -161,6 +168,10 @@ else if (patternAndMethodMatches.isEmpty() && !allowedMethods.isEmpty()) {
161168
else if (!producibleMediaTypes.isEmpty()) {
162169
throw new HttpMediaTypeNotAcceptableException(new ArrayList<MediaType>(producibleMediaTypes));
163170
}
171+
else if (!CollectionUtils.isEmpty(paramConditions)) {
172+
String[] params = paramConditions.toArray(new String[paramConditions.size()]);
173+
throw new UnsatisfiedServletRequestParameterException(params, request.getParameterMap());
174+
}
164175
else {
165176
return null;
166177
}
@@ -186,4 +197,18 @@ private Set<MediaType> getProdicubleMediaTypes(HttpServletRequest request, Set<R
186197
return result;
187198
}
188199

200+
private Set<String> getRequestParams(HttpServletRequest request, Set<RequestMappingInfo> partialMatches) {
201+
for (RequestMappingInfo partialMatch : partialMatches) {
202+
ParamsRequestCondition condition = partialMatch.getParamsCondition();
203+
if (!CollectionUtils.isEmpty(condition.getExpressions()) && (condition.getMatchingCondition(request) == null)) {
204+
Set<String> expressions = new HashSet<String>();
205+
for (NameValueExpression expr : condition.getExpressions()) {
206+
expressions.add(expr.toString());
207+
}
208+
return expressions;
209+
}
210+
}
211+
return null;
212+
}
213+
189214
}

org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2011 the original author or authors.
2+
* Copyright 2002-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@
3939
import org.springframework.web.HttpMediaTypeNotAcceptableException;
4040
import org.springframework.web.HttpMediaTypeNotSupportedException;
4141
import org.springframework.web.HttpRequestMethodNotSupportedException;
42+
import org.springframework.web.bind.UnsatisfiedServletRequestParameterException;
4243
import org.springframework.web.bind.annotation.RequestBody;
4344
import org.springframework.web.bind.annotation.RequestMapping;
4445
import org.springframework.web.bind.annotation.RequestMethod;
@@ -195,6 +196,19 @@ private void testMediaTypeNotAccepted(String url) throws Exception {
195196
}
196197
}
197198

199+
@Test
200+
public void testUnsatisfiedServletRequestParameterException() throws Exception {
201+
try {
202+
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/params");
203+
this.mapping.getHandler(request);
204+
fail("UnsatisfiedServletRequestParameterException expected");
205+
}
206+
catch (UnsatisfiedServletRequestParameterException ex) {
207+
assertArrayEquals("Invalid request parameter conditions",
208+
new String[] { "foo=bar" }, ex.getParamConditions());
209+
}
210+
}
211+
198212
@Test
199213
public void uriTemplateVariables() {
200214
PatternsRequestCondition patterns = new PatternsRequestCondition("/{path1}/{path2}");
@@ -300,6 +314,11 @@ public String produces() {
300314
return "";
301315
}
302316

317+
@RequestMapping(value = "/params", params="foo=bar")
318+
public String param() {
319+
return "";
320+
}
321+
303322
@RequestMapping(value = "/content", produces="application/xml")
304323
public String xmlContent() {
305324
return "";

0 commit comments

Comments
 (0)