Spring MVC控制器的Ajax POST对象数组-多个错误

时间:2019-05-09 16:24:34

标签: ajax spring spring-boot spring-mvc

我需要将一个JS形式的对象数组提交给Spring MVC Controller。所有属性名称都匹配。

@PostMapping("/addAdmin")
public void addAdmin(@RequestParam List<UserRolesGUIBean> userRolesGUIBeans)
{
    // ...      
}   

JS:

 var entries = [];
 //...
 // entries is an array of objects of the form {id: "..", role: ".."}
 // verified to be correct before submission

 $.ajax({
        type : "post",
        dataType : "json", 
        url : 'addAdmin',  
        data : JSON.stringify(entries)
 })

Bean

public class UserRolesGUIBean implements Serializable {
    private String id;
    private String role;
    // + Constructors (Empty + Full), Getters and setters
}

错误:

Required List parameter 'userRolesGUIBeans' is not present]

还尝试了ModelAttributeArrayList的问题,

PostMapping("/addAdmin")
    public void addAdmin(@ModelAttribute ArrayList<UserRolesGUIBean> userRolesGUIBeans)  {

现在没有错误,但是列表为空,没有收到数据

对所有内容都进行了尝试-数组与列表,JSON.stringify(data)或带有data {"entries" : entries}RequestBody的数据对象不起作用,并给出UTF错误;和上面的RequestParam也不起作用。

对于一个简单的任务来说,这太复杂了。

3 个答案:

答案 0 :(得分:0)

您正尝试使用帖子发送JSON对象。您应该使用@RequestBody批注。

尝试以这种方式更改您的方法:

@PostMapping("/addAdmin")
public void addAdmin(@RequestBody List<UserRolesGUIBean> userRolesGUIBeans)
{
    // ...      
} 

通过这种方式,Spring将拦截Json并将其转换为所需对象列表

答案 1 :(得分:0)

解决方案

1)从理论上讲,如果我正在进行表单提交(例如$('#myForm').submit()),则可以使用@ModelAttribute将表单自动绑定到Bean。这就是@ModelAttribute所做的-用于表单提交。我没有真实的形式;只有我自己的自定义值。

我仍然可以通过“动态”创建动态表单来“伪造”表单提交,但是我无法获得Arrayed-Field表单提交(例如obj[][] HTML名称中的符号)映射到@ModelAttribute List<Bean>,因此我忽略了这种不寻常的表单提交方法。

2)有效的方法是只提交我自己的自定义JSON字符串。与任何表单提交都不相关,因此不能使用@ModelAttribute。相反,这是@RequestBody方法。然后,我必须自己解析JSON RequestBody字符串-在这里,我们必须使用Jackson,Java JSON或GSON来解析JSON数组。

就我而言,

JS:

 $.ajax({
        type : "post",
        dataType : 'json', 
        url : 'addAdmin',  
        data : JSON.stringify(entries)
 })

控制器(请注意,它仅使用自定义字符串)。然后它使用Jackson手动解析字符串,因为在这种情况下Spring不会这样做。 (只有在使用@ModelAttribute表单绑定时,Spring才会自动解析。)

@PostMapping("/addAdmin")
public boolean addAdmin(@RequestBody String json) throws Exception {

      String decodedJson = java.net.URLDecoder.decode(json, "UTF-8");
      ObjectMapper jacksonObjectMapper = new ObjectMapper(); // This is Jackson
      List<UserRolesGUIBean> userRolesGUIBeans =  jacksonObjectMapper.readValue(
              decodedJson, new TypeReference<List<UserRolesGUIBean>>(){});
      // Now I have my list of beans populated.

}

答案 2 :(得分:0)

如所承诺的,请转到https://start.spring.io/,并为spring-boot-starter-web创建一个具有唯一依赖关系的新项目。

之后,您可以在项目中创建以下bean。

import java.util.List;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {
    @PostMapping("/request-body")
    public void getRequestBody(@RequestBody List<Person> list) {
        for (Person person : list) {
            System.out.println(person.name);
        }
    }

    public static class Person {
        private String name;
        private String phoneNo;

        /**
         * @return the name
         */
        public String getName() {
            return name;
        }
        /**
         * @param name the name to set
         */
        public void setName(String name) {
            this.name = name;
        }
        /**
         * @return the phoneNo
         */
        public String getPhoneNo() {
            return phoneNo;
        }
        /**
         * @param phoneNo the phoneNo to set
         */
        public void setPhoneNo(String phoneNo) {
            this.phoneNo = phoneNo;
        }
    }
}

没什么特别的,只需输入Person的列表并打印出名称即可。您可以右键单击并直接从IDE运行项目。

您可以打开Postman并按以下步骤发出POST请求。

enter image description here enter image description here

这是在控制台中打印的内容。

enter image description here

如果与Postman一起使用,则可以使其在JS中工作。您只是还不知道如何。我认为您应该找到在JS中提交请求的正确方法,而不是解决您发现的“解决方法”。另外,对Spring框架的一些了解也将有所帮助。否则,您将继续尝试@ModelAttribute之类的东西,而无所事事。