2012-08-24 131 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>