我正在spring3项目中尝试使用Scala,当我使用@ResponseBody返回地图时,我没有得到我期望的结果。我在java中包含了一个工作示例以及我在scala中的尝试
// 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;
}
java返回json与pbx&amp;方法定义,这是我所期待的。
// This is Scala
@RequestMapping(value= Array("/pbx.admin"),
method=Array(RequestMethod.GET))
@ResponseBody
def getInfo2() = {
Map("pbx" -> "admin", "method" -> "s")
}
scala返回了不同的东西:
{
empty: false,
traversableAgain: true
}
为了获取地图键/值,我需要做什么?
为了额外的功劳,有没有更好的'scala方式'来做到这一点?谢谢!
答案 0 :(得分:8)
Spring MVC框架不是用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集合,但显然不是开箱即用。
答案 1 :(得分:7)
Spring MVC使用Jackson。您需要将Jackson scala模块注册为映射器。这增加了对杰克逊的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上
答案 2 :(得分:0)
Scala模块需要序列化Scala对象,例如Collections,Option和case类。这是一种仅通过修改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>