Using a map to set parameters for a rest call using RestTemplate

Emi*_*and 6 java spring spring-mvc spring-restcontroller

I am currently using a piece of code to set parameters and I do a REST call to a URL using restTemplate, it works fine:

MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("grant_type", grantType);
map.add("client_id", clientId);
map.add("client_secret", clientSecret);
HttpEntity<?> entity = new HttpEntity<Object>(map);
restTemplate.exchange("myurl", HttpMethod.POST, entity, Void.class);
Run Code Online (Sandbox Code Playgroud)

But if I am using a LinkedMultiValueMap it's because I looked on the web ;)

And if I replace it by a HashMap, it works as well, so can anyone tell me the advantage of using a LinkedMultiValueMap ?

Code with HashMap:

Map<String, String> map = new HashMap<String, String>();
map.put("grant_type", grantType);
map.put("client_id", clientId);
map.put("client_secret", clientSecret);
HttpEntity<?> entity = new HttpEntity<Object>(map);
restTemplate.exchange("myurl", HttpMethod.POST, entity, Void.class);
Run Code Online (Sandbox Code Playgroud)

I can see we can preserve the order of the parameters in the LinkedMultiValueMap, but it does not matter in my project... And so if orders matters I still could use a LinkedHashMap

EDIT:

It looks like I need the MultiValueMap if I use APPLICATION_FORM_URLENCODED and HashMap, this code throw an exception :

Map<String, String> map = new HashMap<String, String>();
map.add("grant_type", grantType);
map.add("client_id", clientId);
map.add("client_secret", clientSecret);
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<?> entity = new HttpEntity<Object>(map, headers);
restTemplate.exchange("myurl", HttpMethod.POST, entity, Void.class);
Run Code Online (Sandbox Code Playgroud)

Exception:

org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [java.util.HashMap] and content type [application/x-www-form-urlencoded]
        at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:784)
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:567)
        at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:530)
        at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:448)
        at uk.co.wowcher.marketplace.commons.rest.RestTemplateUtils.getForEntity(RestTemplateUtils.java:54)
        at uk.co.wowcher.marketplace.submission.service.ParameterService.getProductParameterVOs(ParameterService.java:38)
        at uk.co.wowcher.marketplace.submission.service.ParameterService$$FastClassBySpringCGLIB$$3f87231d.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
        at uk.co.wowcher.marketplace.submission.logging.MarketplaceLogger.logMethodCalls(MarketplaceLogger.java:27)
        at sun.reflect.GeneratedMethodAccessor72.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
        at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
        at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
        at uk.co.xxx.marketplace.submission.service.ParameterService$$EnhancerBySpringCGLIB$$a52b80b.getProductParameterVOs(<generated>)
        at uk.co.xxx.marketplace.submission.service.SubmissionService.getAgreementData(SubmissionService.java:449)
       at uk.co.xxx.marketplace.submission.service.SubmissionService$$FastClassBySpringCGLIB$$92bbe798.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
Run Code Online (Sandbox Code Playgroud)

So, it looks like that setting some parameters with a HashMap is not a good idea at all... So I removed the accepted answer for now, waiting more explanation on this point... And I have the suitable converter (converters.add(new FormHttpMessageConverter());), I mean if I use a MultiValueMap I don't have the exception, so the HashMap is the problem!

小智 5

The only real advantage of using a LinkedMultiValueMap over other Map implementations is that it can store multiple values.

如果您需要为同一个键传递多个值(例如,如果您需要传递一组表单复选框值),这将很有用。

此处查看JavaDoc 。

在您的情况下,由于每个键只有一个值,因此您应该可以安全地使用HashMap


Kan*_*j M 0

MultiValueMapMap(key:ArrayOfValues[])用于为单个 KEY( )存储多个值,同时LinkedMultiValueMap执行相同的操作但保持插入顺序。在您的情况下,HashMap这已经足够了,因为LinkedMultiValueMap性能会比您的场景慢HashMap并且HashMap不是您的场景所必需的。