Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring Scala、@ResponseBody和Map_Spring_Scala_Spring Mvc - Fatal编程技术网

Spring Scala、@ResponseBody和Map

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

我正在spring3项目中试验Scala,但当我返回带有@ResponseBy的地图时,并没有得到我所期望的结果。我在scala中的尝试中加入了一个java的工作示例

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