Skip to content

Commit 3c09b07

Browse files
committed
Raise exception on missing request parameters
Issue: SPR-10193
1 parent 4d01d43 commit 3c09b07

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,19 @@
2828
import javax.servlet.http.HttpServletRequest;
2929

3030
import org.springframework.http.MediaType;
31+
import org.springframework.util.CollectionUtils;
3132
import org.springframework.util.MultiValueMap;
3233
import org.springframework.util.StringUtils;
3334
import org.springframework.web.HttpMediaTypeNotAcceptableException;
3435
import org.springframework.web.HttpMediaTypeNotSupportedException;
3536
import org.springframework.web.HttpRequestMethodNotSupportedException;
37+
import org.springframework.web.bind.UnsatisfiedServletRequestParameterException;
3638
import org.springframework.web.bind.annotation.RequestMethod;
3739
import org.springframework.web.method.HandlerMethod;
3840
import org.springframework.web.servlet.HandlerMapping;
3941
import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
42+
import org.springframework.web.servlet.mvc.condition.NameValueExpression;
43+
import org.springframework.web.servlet.mvc.condition.ParamsRequestCondition;
4044
import org.springframework.web.util.WebUtils;
4145

4246
/**
@@ -185,14 +189,17 @@ else if (patternAndMethodMatches.isEmpty() && !allowedMethods.isEmpty()) {
185189

186190
Set<MediaType> consumableMediaTypes;
187191
Set<MediaType> producibleMediaTypes;
192+
Set<String> paramConditions;
188193

189194
if (patternAndMethodMatches.isEmpty()) {
190195
consumableMediaTypes = getConsumableMediaTypes(request, patternMatches);
191196
producibleMediaTypes = getProdicubleMediaTypes(request, patternMatches);
197+
paramConditions = getRequestParams(request, patternMatches);
192198
}
193199
else {
194200
consumableMediaTypes = getConsumableMediaTypes(request, patternAndMethodMatches);
195201
producibleMediaTypes = getProdicubleMediaTypes(request, patternAndMethodMatches);
202+
paramConditions = getRequestParams(request, patternAndMethodMatches);
196203
}
197204

198205
if (!consumableMediaTypes.isEmpty()) {
@@ -205,6 +212,10 @@ else if (patternAndMethodMatches.isEmpty() && !allowedMethods.isEmpty()) {
205212
else if (!producibleMediaTypes.isEmpty()) {
206213
throw new HttpMediaTypeNotAcceptableException(new ArrayList<MediaType>(producibleMediaTypes));
207214
}
215+
else if (!CollectionUtils.isEmpty(paramConditions)) {
216+
String[] params = paramConditions.toArray(new String[paramConditions.size()]);
217+
throw new UnsatisfiedServletRequestParameterException(params, request.getParameterMap());
218+
}
208219
else {
209220
return null;
210221
}
@@ -230,4 +241,18 @@ private Set<MediaType> getProdicubleMediaTypes(HttpServletRequest request, Set<R
230241
return result;
231242
}
232243

244+
private Set<String> getRequestParams(HttpServletRequest request, Set<RequestMappingInfo> partialMatches) {
245+
for (RequestMappingInfo partialMatch : partialMatches) {
246+
ParamsRequestCondition condition = partialMatch.getParamsCondition();
247+
if (!CollectionUtils.isEmpty(condition.getExpressions()) && (condition.getMatchingCondition(request) == null)) {
248+
Set<String> expressions = new HashSet<String>();
249+
for (NameValueExpression expr : condition.getExpressions()) {
250+
expressions.add(expr.toString());
251+
}
252+
return expressions;
253+
}
254+
}
255+
return null;
256+
}
257+
233258
}

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.springframework.web.HttpMediaTypeNotAcceptableException;
4343
import org.springframework.web.HttpMediaTypeNotSupportedException;
4444
import org.springframework.web.HttpRequestMethodNotSupportedException;
45+
import org.springframework.web.bind.UnsatisfiedServletRequestParameterException;
4546
import org.springframework.web.bind.annotation.RequestBody;
4647
import org.springframework.web.bind.annotation.RequestMapping;
4748
import org.springframework.web.bind.annotation.RequestMethod;
@@ -202,6 +203,19 @@ private void testMediaTypeNotAccepted(String url) throws Exception {
202203
}
203204
}
204205

206+
@Test
207+
public void testUnsatisfiedServletRequestParameterException() throws Exception {
208+
try {
209+
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/params");
210+
this.handlerMapping.getHandler(request);
211+
fail("UnsatisfiedServletRequestParameterException expected");
212+
}
213+
catch (UnsatisfiedServletRequestParameterException ex) {
214+
assertArrayEquals("Invalid request parameter conditions",
215+
new String[] { "foo=bar" }, ex.getParamConditions());
216+
}
217+
}
218+
205219
@Test
206220
public void uriTemplateVariables() {
207221
PatternsRequestCondition patterns = new PatternsRequestCondition("/{path1}/{path2}");
@@ -414,6 +428,11 @@ public String produces() {
414428
return "";
415429
}
416430

431+
@RequestMapping(value = "/params", params="foo=bar")
432+
public String param() {
433+
return "";
434+
}
435+
417436
@RequestMapping(value = "/content", produces="application/xml")
418437
public String xmlContent() {
419438
return "";

0 commit comments

Comments
 (0)