#209 - Added support for Map<String, String> and MultiValueMap<String, String> RequestParams in ControllerLinkBuilderFactory.

Original pull request: #210.
This commit is contained in:
rossturner
2014-07-03 09:55:06 +01:00
committed by Oliver Gierke
parent 912337669a
commit 65f0c451d5
2 changed files with 66 additions and 22 deletions

View File

@@ -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<Co
Object value = parameter.getValue();
String key = parameter.getVariableName();
if (value instanceof Collection) {
if (value instanceof MultiValueMap<?, ?>) {
MultiValueMap<String, String> requestParams = (MultiValueMap<String, String>)value;
for (Map.Entry<String, List<String>> multiValueEntry : requestParams.entrySet()) {
for (String singleEntryValue : multiValueEntry.getValue()) {
builder.queryParam(multiValueEntry.getKey(), singleEntryValue);
}
}
} else if (value instanceof Map<?, ?>) {
Map<String, String> requestParams = (Map<String, String>)value;
for (Map.Entry<String, String> requestParamEntry : requestParams.entrySet()) {
builder.queryParam(requestParamEntry.getKey(), requestParamEntry.getValue());
}
} else if (value instanceof Collection) {
for (Object element : (Collection<?>) value) {
builder.queryParam(key, element);
}

View File

@@ -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<String, String> queryParams = new LinkedHashMap<String, String>();
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<String, String> queryParams = new LinkedMultiValueMap<String, String>();
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<String, String> queryParams);
@RequestMapping("/sample/multivaluemapsupport")
HttpEntity<?> sampleMethodWithMap(@RequestParam MultiValueMap<String, String> queryParams);
}
static class SampleUriComponentsContributor implements UriComponentsContributor {