2012-08-24 134 views
2

我正在Spring3项目中尝试Scala,并且当我使用@ResponseBody返回地图时,我得不到我期望的结果。我包括在Java中的工作示例以及我尝试在斯卡拉斯卡拉,@ResponseBody和地图

// 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 &方法,这是我很期待。

// This is Scala 
@RequestMapping(value= Array("/pbx.admin"), 
    method=Array(RequestMethod.GET)) 
@ResponseBody 
def getInfo2() = { 
    Map("pbx" -> "admin", "method" -> "s") 
} 

斯卡拉返回不同的东西,但:

{ 
    empty: false, 
    traversableAgain: true 
} 

我需要做什么才能让我的映射键/值呢?

为了额外的功劳,有没有更好的'scala方式'来做到这一点?谢谢!

回答

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

谢谢!这工作很好。 – samspot

+4

因此,当Spring MVC没有将scala.collection.Map识别为Map时,它决定应用它用来序列化JavaBean的策略,即找到所有符合JavaBean约定的方法,并将它们用作JSON对象。有两种方法符合这些标准:'isEmpty'和'isTraversableAgain'。 –

+1

@KenBloom:确切地说,对于伟大的评论+1。当你尝试返回Scala的'List'时会发生类似的事情。 –

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在https://github.com/FasterXML/jackson-module-scala

0

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>