Spring Scala、@ResponseBody和Map
我正在spring3项目中试验Scala,但当我返回带有@ResponseBy的地图时,并没有得到我所期望的结果。我在scala中的尝试中加入了一个java的工作示例Spring Scala、@ResponseBody和Map,spring,scala,spring-mvc,Spring,Scala,Spring Mvc,我正在spring3项目中试验Scala,但当我返回带有@ResponseBy的地图时,并没有得到我所期望的结果。我在scala中的尝试中加入了一个java的工作示例 // This is Java @RequestMapping(value="/pbx.admin", method=RequestMethod.GET) public @ResponseBody Map<String, Object> getInfo2(HttpServletRequest request, Mode
// This is Java
@RequestMapping(value="/pbx.admin", method=RequestMethod.GET)
public @ResponseBody Map<String, Object> getInfo2(HttpServletRequest request, Model model){
Map<String, Object> map = new HashMap<String, Object>();
map.put("pbx", "admin");
map.put("method", "s");
return map;
}
scala返回了一些不同的结果:
{
empty: false,
traversableAgain: true
}
要获取地图键/值,我需要做什么
对于额外的积分,有没有更好的“scala方法”来做到这一点?谢谢 springmvc框架不是在考虑Scala的情况下构建的,它也不认识Scala的
Map
。您必须将scala.collection.Map
转换为java.util.Map
。您可以使用隐式转换:
import collection.JavaConversions._
def getInfo2(): java.util.Map[String, String] = {
Map("pbx" -> "admin", "method" -> "s")
}
或手动转换:
import collection.JavaConverters._
def getInfo2() = {
Map("pbx" -> "admin", "method" -> "s").asJava
}
注意进口,它们很重要
我怀疑Spring可能被黑客攻击接受Scala集合,但显然不是现成的。Spring MVC使用Jackson。您需要将Jackson scala模块注册为映射器。这为Jackson添加了对scala的支持,使其能够识别这些集合 例如:
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.ScalaModule
import com.fasterxml.jackson.module.scala.DefaultScalaModule
class ScalaObjectMapper extends ObjectMapper {
{
registerModule(DefaultScalaModule)
}
}
然后,您需要将其添加到消息转换器中
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.petzfactor.packwall.web.module.ScalaObjectMapper"></bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
该模块位于github上的Scala模块是序列化Scala对象(如集合、选项和案例类)所必需的。下面是一种仅通过修改Spring上下文来注册Jackson Scala模块的方法
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="objectMapperWithScala"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean name="scalaModule" class="com.fasterxml.jackson.module.scala.DefaultScalaModule"/>
<bean name="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper"/>
<bean name="objectMapperWithScala" factory-bean="objectMapper" factory-method="registerModule">
<constructor-arg ref="scalaModule"/>
</bean>
因此,当Spring MVC没有将scala.collection.Map识别为映射时,它决定应用它用来序列化JavaBean的策略,即找到所有符合JavaBean约定的方法,并将它们用作JSON对象的元素。有两种方法可以满足这些标准:isEmpty
和isTraversableAgain
@KenBloom:没错,+1表示非常好的评论。当您尝试返回Scala的列表时,也会发生类似的情况,我期望的是在编译时将我的映射转换为java.util.HashMap,但我是Scala新手:)
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="objectMapperWithScala"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean name="scalaModule" class="com.fasterxml.jackson.module.scala.DefaultScalaModule"/>
<bean name="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper"/>
<bean name="objectMapperWithScala" factory-bean="objectMapper" factory-method="registerModule">
<constructor-arg ref="scalaModule"/>
</bean>