使用地图为使用RestTemplate的Rest调用设置参数 - java

我目前正在使用一段代码来设置参数,并且我使用restTemplate对URL进行了REST调用,效果很好:

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);

但是,如果我使用的是LinkedMultiValueMap,那是因为我在网上查看了;)

而且,如果我将其替换为HashMap,它也可以正常工作,因此有人可以告诉我使用LinkedMultiValueMap的优势吗?

带有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);

我可以看到我们可以保留LinkedMultiValueMap中参数的顺序,但这在我的项目中没有关系...因此,如果顺序很重要,我仍然可以使用LinkedHashMap
编辑:

如果我使用APPLICATION_FORM_URLENCODED和HashMap,似乎需要MultiValueMap,此代码将引发异常:

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);

例外:

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)

因此,似乎用HashMap设置一些参数根本不是一个好主意...
因此,我暂时删除了可接受的答案,在这一点上等待更多的解释...
而且我有合适的转换器(converters.add(new FormHttpMessageConverter());),我的意思是如果我使用MultiValueMap我没有例外,所以HashMap就是问题!

参考方案

与其他LinkedMultiValueMap实现相比,使用Map的唯一真正优势是它可以存储多个值。

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

请参阅JavaDoc here。

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

Spring MVC中的输入验证 - java

我知道Commons Validator框架是Struts项目在服务器端和客户端验证输入值的事实上的标准。Spring MVC项目是否也是如此?我得到的印象可能不是,大多数Struts书籍和论坛都谈论Commons Validator框架,但是只有少数Spring书籍和论坛可以。在Spring MVC项目中验证输入的最佳实践是什么?干杯! 参考方案 在引入S…

Spring Security不允许加载CSS或JS资源 - java

该资源位于src / main / resources / static / css或src / main / resources / static / js下,我使用的是Spring Boot,安全级别为:@Configuration @EnableWebMvcSecurity @EnableGlobalAuthentication public clas…

Java:“自动装配”继承与依赖注入 - java

Improve this question 我通常以常见的简单形式使用Spring框架: 控制器服务存储库通常,我会在CommonService类中放一个通用服务,并使所有其他服务扩展到类中。一个开发人员告诉我,最好在每个服务中插入CommonClass而不是使用继承。我的问题是,有一个方法比另一个更好吗? JVM或性能是否会受到另一个影响?更新资料Comm…

Spring MVC Web应用程序检测暴力攻击的最佳方法? - java

Spring 3.0 MVC中是否有专门用于帮助检测Web应用程序的身份验证/登录页面上的蛮力攻击的功能? 参考方案 经过长期验证的实践是,如果身份验证失败,则会引入随机但相当大的延迟。这样,合法用户将立即登录,但攻击者每次尝试将花费500ms-1s,这使整个暴力概念不切实际(将永远存在)。合法用户偶尔失败的登录只会使他们稍有延迟,并且不会引起注意。如果需要…

Spring中的应用程序上下文有什么作用? - java

我昨天问了一个问题(Using Spring in standalone apps),有关如何在独立应用程序中使用Spring。由此得知,您只创建一次应用程序上下文对象。因此,现在的问题是(即使在评论中得到了部分回答)创建应用程序上下文时会发生什么?当您说时,Spring是否会创建这些豆子并将它们连接在一起new ClassPathXmlApplicatio…