diff --git a/src/main/java/org/springframework/hateoas/mvc/ControllerLinkBuilderFactory.java b/src/main/java/org/springframework/hateoas/mvc/ControllerLinkBuilderFactory.java index be13d85f..cdea9240 100644 --- a/src/main/java/org/springframework/hateoas/mvc/ControllerLinkBuilderFactory.java +++ b/src/main/java/org/springframework/hateoas/mvc/ControllerLinkBuilderFactory.java @@ -15,28 +15,15 @@ */ package org.springframework.hateoas.mvc; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - import org.springframework.core.MethodParameter; import org.springframework.hateoas.Link; import org.springframework.hateoas.MethodLinkBuilderFactory; -import org.springframework.hateoas.core.AnnotationAttribute; -import org.springframework.hateoas.core.AnnotationMappingDiscoverer; +import org.springframework.hateoas.core.*; import org.springframework.hateoas.core.DummyInvocationUtils.LastInvocationAware; import org.springframework.hateoas.core.DummyInvocationUtils.MethodInvocation; -import org.springframework.hateoas.core.LinkBuilderSupport; -import org.springframework.hateoas.core.MappingDiscoverer; -import org.springframework.hateoas.core.MethodParameters; import org.springframework.hateoas.mvc.AnnotatedParametersParameterAccessor.BoundMethodParameter; import org.springframework.util.Assert; +import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -44,6 +31,9 @@ import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriTemplate; +import java.lang.reflect.Method; +import java.util.*; + /** * Factory for {@link LinkBuilderSupport} instances based on the request mapping annotated on the given controller. * @@ -133,7 +123,19 @@ public class ControllerLinkBuilderFactory implements MethodLinkBuilderFactory) { + MultiValueMap requestParams = (MultiValueMap)value; + for (Map.Entry> multiValueEntry : requestParams.entrySet()) { + for (String singleEntryValue : multiValueEntry.getValue()) { + builder.queryParam(multiValueEntry.getKey(), singleEntryValue); + } + } + } else if (value instanceof Map) { + Map requestParams = (Map)value; + for (Map.Entry requestParamEntry : requestParams.entrySet()) { + builder.queryParam(requestParamEntry.getKey(), requestParamEntry.getValue()); + } + } else if (value instanceof Collection) { for (Object element : (Collection) value) { builder.queryParam(key, element); } diff --git a/src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderFactoryUnitTest.java b/src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderFactoryUnitTest.java index 7e050373..031d0b79 100644 --- a/src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderFactoryUnitTest.java +++ b/src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderFactoryUnitTest.java @@ -15,12 +15,6 @@ */ package org.springframework.hateoas.mvc; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; -import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*; - -import java.util.Arrays; - import org.joda.time.DateTime; import org.joda.time.format.ISODateTimeFormat; import org.junit.Test; @@ -33,10 +27,23 @@ import org.springframework.hateoas.mvc.ControllerLinkBuilderUnitTest.ControllerW import org.springframework.hateoas.mvc.ControllerLinkBuilderUnitTest.PersonControllerImpl; import org.springframework.hateoas.mvc.ControllerLinkBuilderUnitTest.PersonsAddressesController; import org.springframework.http.HttpEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.util.UriComponentsBuilder; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; + +import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; + /** * Unit tests for {@link ControllerLinkBuilderFactory}. * @@ -119,6 +126,35 @@ public class ControllerLinkBuilderFactoryUnitTest extends TestUtils { assertThat(link.getHref(), endsWith("/people/with%20blank/addresses")); } + /** + * @see #209 + */ + @Test + public void createsLinkToControllerMethodWithMapRequestParam() { + Map queryParams = new LinkedHashMap(); + queryParams.put("firstKey", "firstValue"); + queryParams.put("secondKey", "secondValue"); + + Link link = factory.linkTo(methodOn(SampleController.class).sampleMethodWithMap(queryParams)).withSelfRel(); + + assertPointsToMockServer(link); + assertThat(link.getRel(), is(Link.REL_SELF)); + assertThat(link.getHref(), endsWith("/sample/mapsupport?firstKey=firstValue&secondKey=secondValue")); + } + + @Test + public void createsLinkToControllerMethodWithMultiValueMapRequestParam() { + MultiValueMap queryParams = new LinkedMultiValueMap(); + queryParams.put("key1", Arrays.asList("value1a", "value1b")); + queryParams.put("key2", Arrays.asList("value2a", "value2b")); + + Link link = factory.linkTo(methodOn(SampleController.class).sampleMethodWithMap(queryParams)).withSelfRel(); + + assertPointsToMockServer(link); + assertThat(link.getRel(), is(Link.REL_SELF)); + assertThat(link.getHref(), endsWith("/sample/multivaluemapsupport?key1=value1a&key1=value1b&key2=value2a&key2=value2b")); + } + static interface SampleController { @RequestMapping("/sample/{id}") @@ -126,6 +162,12 @@ public class ControllerLinkBuilderFactoryUnitTest extends TestUtils { @RequestMapping("/sample/{time}") HttpEntity sampleMethod(@PathVariable("time") @DateTimeFormat(iso = ISO.DATE) DateTime time); + + @RequestMapping("/sample/mapsupport") + HttpEntity sampleMethodWithMap(@RequestParam Map queryParams); + + @RequestMapping("/sample/multivaluemapsupport") + HttpEntity sampleMethodWithMap(@RequestParam MultiValueMap queryParams); } static class SampleUriComponentsContributor implements UriComponentsContributor {