From 2cdcf752ba830e4d641842ea1b3c546011d04284 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 27 Jun 2016 16:02:54 -0400 Subject: [PATCH] MvcUriComponentsBuilder respects optional params Issue: SPR-14405 --- .../RequestParamMethodArgumentResolver.java | 5 +++ .../MvcUriComponentsBuilderTests.java | 35 +++++++++++++------ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java index fc1e75b8a3..5f6452cd4b 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java @@ -211,6 +211,11 @@ public class RequestParamMethodArgumentResolver extends AbstractNamedValueMethod parameter.getParameterName() : requestParam.name()); if (value == null) { + if (requestParam != null) { + if (!requestParam.required() || !requestParam.defaultValue().equals(ValueConstants.DEFAULT_NONE)) { + return; + } + } builder.queryParam(name); } else if (value instanceof Collection) { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java index 49f204efd3..daa1108aed 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -221,6 +221,14 @@ public class MvcUriComponentsBuilderTests { assertThat(uriComponents.toUriString(), is("http://localhost/input")); } + @Test // SPR-14405 + public void testFromMappingNameWithOptionalParam() throws Exception { + UriComponents uriComponents = fromMethodName(ControllerWithMethods.class, + "methodWithOptionalParam", new Object[] {null}).build(); + + assertThat(uriComponents.toUriString(), is("http://localhost/something/optional-param")); + } + @Test public void testFromMethodCall() { UriComponents uriComponents = fromMethodCall(on(ControllerWithMethods.class).myMethod(null)).build(); @@ -369,25 +377,25 @@ public class MvcUriComponentsBuilderTests { } - class PersonControllerImpl implements PersonController { + private class PersonControllerImpl implements PersonController { } @RequestMapping("/people/{id}/addresses") - static class PersonsAddressesController { + private static class PersonsAddressesController { @RequestMapping("/{country}") - public HttpEntity getAddressesForCountry(@PathVariable String country) { + HttpEntity getAddressesForCountry(@PathVariable String country) { return null; } } @RequestMapping({ "/persons", "/people" }) - class InvalidController { + private class InvalidController { } - class UnmappedController { + private class UnmappedController { @RequestMapping public void unmappedMethod() { @@ -424,15 +432,20 @@ public class MvcUriComponentsBuilderTests { @RequestParam List items, @RequestParam Integer limit) { return null; } + + @RequestMapping("/optional-param") + HttpEntity methodWithOptionalParam(@RequestParam(defaultValue = "") String q) { + return null; + } } - @RequestMapping("/extended") + @RequestMapping("/extended") @SuppressWarnings("WeakerAccess") static class ExtendedController extends ControllerWithMethods { } @RequestMapping("/user/{userId}/contacts") - static class UserContactController { + private static class UserContactController { @RequestMapping("/create") public String showCreate(@PathVariable Integer userId) { @@ -445,7 +458,7 @@ public class MvcUriComponentsBuilderTests { abstract T get(ID id); } - static class PersonCrudController extends AbstractCrudController { + private static class PersonCrudController extends AbstractCrudController { @RequestMapping(path = "/{id}", method = RequestMethod.GET) public Person get(@PathVariable Long id) { @@ -454,7 +467,7 @@ public class MvcUriComponentsBuilderTests { } @Controller - static class MetaAnnotationController { + private static class MetaAnnotationController { @RequestMapping public void handle() { @@ -472,7 +485,7 @@ public class MvcUriComponentsBuilderTests { @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented - @interface PostJson { + private @interface PostJson { String[] path() default {}; }