将Map <String,String>传递给springMVC控制器

azp*_*lic 7 ajax spring json spring-mvc

我试图从ajax发送HashMap或任何其他Map实现到Spring MVC控制器

这是我如何做的细节:

Ajax调用如下

var tags = {};
tags["foo"] = "bar";
tags["whee"] = "whizzz";


$.post("doTestMap.do",   {"tags" : tags }, function(data, textStatus, jqXHR) {
if (textStatus == 'success') {
    //handle success
    console.log("doTest returned " + data);
} else {
    console.err("doTest returned " + data);
}
}); 
Run Code Online (Sandbox Code Playgroud)

那么在控制器方面我有:

@RequestMapping(value="/publisher/doTestMap.do", method=RequestMethod.POST)
public @ResponseBody String doTestMap(@RequestParam(value = "tags", defaultValue = "") HashMap<String,String> tags, HttpServletRequest request) {  //

    System.out.println(tags);

    return "cool";
} 
Run Code Online (Sandbox Code Playgroud)

不幸的是我系统地得到了

org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Map'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Map]: no matching editors or conversion strategy found
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么 ?

谢谢.

Mar*_*rey 12

在弹簧控制器中绑定地图的方式与绑定数组的方式相同.无需特殊转换器!

但有一件事要记住:

  • Spring使用命令对象作为顶级值持有者.命令对象可以是任何类.

所以你需要的是一个包装类class(TagsWrapper),它包含一个Map<String, String>名为tags 的类型的字段.绑定数组的方法相同.

在文档中对此进行了很好的解释,但我偶尔忘记了包装器对象的需要;)

您需要更改的第二件事是提交标记值的方式:

  • 每个映射键使用一个表单参数,而不是完整映射的完整字符串表示.
  • 一个输入值应如下所示:

      <input type="text" name="tags[key]" value="something">
    
    Run Code Online (Sandbox Code Playgroud)

如果标签是包装器中的地图,那么这对于表单提交是开箱即用的.


azp*_*lic 5

这是我根据马丁·弗雷(Martin Frey)的帮助完成的答案:

JavaScript端(请注意如何填充标签值):

var data = {
   "tags[foo]" : "foovalue", 
   "tags[whizz]" : "whizzvalue" 
}

$.post("doTestMap.do",   data , function(data, textStatus, jqXHR) {
    ...
}); 
Run Code Online (Sandbox Code Playgroud)

然后在控制器端:

@RequestMapping(value="/publisher/doTestMap.do", method=RequestMethod.POST)
public @ResponseBody String doTestMap(@ModelAttribute MyWrapper wrapper, HttpServletRequest request) {
} 
Run Code Online (Sandbox Code Playgroud)

并在其中包含Map来创建包装器类:

class MyWrapper {

    Map<String,String> tags;

   +getters and setters

}
Run Code Online (Sandbox Code Playgroud)

然后您将适当地填充地图...


小智 5

这可能是迟到的回应。但是,它可能会帮助某人。我有一个类似的问题,这就是我解决的方法。在JS上:“我的地图”看起来像

var values = {};
values[element.id] = element.value;
Run Code Online (Sandbox Code Playgroud)

阿贾克斯:

        $.ajax({
            type : 'POST',
            url : 'xxx.mvc',
            data : JSON.stringify(values),              
            error : function(response) {
                alert("Operation failed.");
            },
            success : function(response) {
                alert("Success");
            },
            contentType : "application/json",
            dataType : "json"
        });
Run Code Online (Sandbox Code Playgroud)

控制器:

@RequestMapping(value = "/xxx.mvc", method=RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> getValues(@RequestBody Map<String, Object> pvmValues, final HttpServletRequest request, final HttpServletResponse response) {
System.out.println(pvmValues.get("key"));
}
Run Code Online (Sandbox Code Playgroud)