将 JSON Map 传递到 Spring MVC 控制器

2022-09-02 10:53:40

我正在尝试将 Map 的 JSON 表示形式作为 POST 参数发送到我的控制器中。

@RequestMapping(value = "/search.do", method = RequestMethod.GET, consumes = { "application/json" })
public @ResponseBody Results search(@RequestParam("filters") HashMap<String,String> filters, HttpServletRequest request) {
       //do stuff
}

我发现@RequestParam只会抛出500错误,所以我尝试使用@ModelAttribute代替。

@RequestMapping(value = "/search.do", method = RequestMethod.GET, consumes = { "application/json" })
public @ResponseBody Results search(@ModelAttribute("filters") HashMap<String,String> filters, HttpServletRequest request) {
       //do stuff
}

这将正确响应请求,但我意识到地图是空的。在后来的实验中,我发现任何对象(不仅仅是HashMap)都会被实例化,但不会填写任何字段。我的类路径上确实有 Jackson,我的控制器将使用 JSON 进行响应。但是,似乎我当前的配置不允许Spring通过GET / POST参数读取JSON。

如何将对象的JSON表示形式从客户端AJAX请求作为请求参数传递到Spring控制器,并取出Java对象?

编辑添加我的相关弹簧配置

  <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="mediaTypes">
      <map>
        <entry key="html" value="text/html" />
        <entry key="json" value="application/json" />
      </map>
    </property>
    <property name="viewResolvers">
      <list>
        <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
          <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
          <property name="prefix" value="/WEB-INF/jsp/" />
          <property name="suffix" value=".jsp" />
        </bean>
      </list>
    </property>
    <property name="defaultViews">
      <list>
        <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
          <property name="prefixJson" value="true" />
        </bean>
      </list>
    </property>
  </bean>
  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
      <list>
        <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
      </list>
    </property>
  </bean>

在评论者的建议下,我尝试了@RequestBody。只要 JSON 字符串用双引号括起来,这就可以了。

@RequestMapping(value = "/search.do", method = RequestMethod.POST, consumes = { "application/json" })
public @ResponseBody Results<T> search(@RequestBody HashMap<String,String> filters, HttpServletRequest request) {
      //do stuff
}

这确实解决了我的直接问题,但我仍然很好奇ou如何通过AJAX调用传入多个JSON对象。


答案 1

这确实解决了我的直接问题,但我仍然很好奇ou如何通过AJAX调用传入多个JSON对象。

执行此操作的最佳方法是具有一个包装器对象,其中包含要传递的两个(或多个)对象。然后,将 JSON 对象构造为两个对象的数组,即

[
  {
    "name" : "object1",
    "prop1" : "foo",
    "prop2" : "bar"
  },
  {
    "name" : "object2",
    "prop1" : "hello",
    "prop2" : "world"
  }
]

然后在控制器方法中,将请求正文作为单个对象接收,并提取两个包含的对象。即:

@RequestMapping(value="/handlePost", method = RequestMethod.POST, 
                consumes = {      "application/json" })
public void doPost(@RequestBody WrapperObject wrapperObj) { 
     Object obj1 = wrapperObj.getObj1;
     Object obj2 = wrapperObj.getObj2;

     //Do what you want with the objects...


}

包装器对象将看起来像...

public class WrapperObject {    
private Object obj1;
private Object obj2;

public Object getObj1() {
    return obj1;
}
public void setObj1(Object obj1) {
    this.obj1 = obj1;
}
public Object getObj2() {
    return obj2;
}
public void setObj2(Object obj2) {
    this.obj2 = obj2;
}   

}

答案 2

您可以使用 Jackson 库从 Json 转换为 Map。

@web上下文.xml

<bean id="messageAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
        </list>
    </property>
</bean>

@maven依赖关系:

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-lgpl</artifactId>
    <version>1.9.13</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-lgpl</artifactId>
    <version>1.9.13</version>
</dependency>

@Controller

@RequestMapping(value = "/method", method = RequestMethod.DELETE)
public String method(
                @RequestBody Map<String, Object> obj){

@Request(例如 jquery Ajax)

$.ajax({"type": "DELETE",
        "contentType": "application/json;",
        "url": "/method",
        "data": JSON.stringify({"key": "Ricardo"}),
        "dataType": "json";}
});

使用Python框架或Play要容易得多!断续器