Scala,@ ResseseBody和Map

时间:2012-08-24 16:12:31

标签: spring scala spring-mvc

我正在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方式'来做到这一点?谢谢!

3 个答案:

答案 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>


该模块位于https://github.com/FasterXML/jackson-module-scala

的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>