Ajax向Spring MVC控制器发布对象数组-多个错误

Ajax向Spring MVC控制器发布对象数组-多个错误,ajax,spring,spring-boot,spring-mvc,Ajax,Spring,Spring Boot,Spring Mvc,我需要向SpringMVC控制器提交一个JS格式的对象数组。所有属性名称都匹配 @PostMapping("/addAdmin") public void addAdmin(@RequestParam List<UserRolesGUIBean> userRolesGUIBeans) { // ... } 豆子 错误: 所需的列表参数“userRolesGUIBeans”不存在] 还使用modeldattribute和ArrayList进行了尝试 Post

我需要向SpringMVC控制器提交一个JS格式的对象数组。所有属性名称都匹配

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

错误:

所需的列表参数“userRolesGUIBeans”不存在]

还使用
modeldattribute
ArrayList
进行了尝试

PostMapping("/addAdmin")
    public void addAdmin(@ModelAttribute ArrayList<UserRolesGUIBean> userRolesGUIBeans)  {
PostMapping(“/addAdmin”)
public void addAdmin(@modeldattribute ArrayList userRolesGUIBeans){
现在没有错误,但是列表是空的,没有收到数据

尝试了一切--数组vs.列表、
JSON.stringify(data)
或带有
data{“entries”:entries}
的数据对象,
RequestBody
不起作用,并给出UTF错误;
RequestParam
如上所述也不起作用


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

您正试图使用post发送JSON对象。您应该使用
@RequestBody
注释

尝试以以下方式更改您的方法:

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

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

您正试图使用post发送Json对象。您应该使用
@RequestBody
注释

尝试以以下方式更改您的方法:

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

通过这种方式,Spring将截获Json并在所需对象列表中转换它

解决方案

1) 理论上,如果我在做表单提交(比如
$(“#myForm”).submit()
),我可以使用
@modeldattribute
自动将表单绑定到bean。这就是
@modeldattribute
所做的——它用于表单提交。我没有真正的表单,只有我自己的自定义值

我仍然可以通过“动态”创建一个动态表单来“伪造”表单提交,但我无法将数组字段表单提交(例如,
obj[]
,在HTML名称中使用
[]
符号)映射到
@modeldattribute List
,因此我忽略了这种不寻常的表单提交方法

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

就我而言

JS:

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

@PostMapping(“/addAdmin”)
公共布尔addAdmin(@RequestBody String json)引发异常{
字符串decodedJson=java.net.urldecover.decode(json,“UTF-8”);
ObjectMapper jacksonObjectMapper=新建ObjectMapper();//这是Jackson
列出userRolesGUIBeans=jacksonObjectMapper.readValue(
decodedJson,新的TypeReference(){});
//现在我已经填充了我的bean列表。

}解决方案

1) 理论上,如果我在做表单提交(比如
$(“#myForm”).submit()
),我可以使用
@modeldattribute
自动将表单绑定到bean。这就是
@modeldattribute
所做的——它用于表单提交。我没有真正的表单,只有我自己的自定义值

我仍然可以通过“动态”创建一个动态表单来“伪造”表单提交,但我无法将数组字段表单提交(例如,
obj[]
,在HTML名称中使用
[]
符号)映射到
@modeldattribute List
,因此我忽略了这种不寻常的表单提交方法

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

就我而言

JS:

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

@PostMapping(“/addAdmin”)
公共布尔addAdmin(@RequestBody String json)引发异常{
字符串decodedJson=java.net.urldecover.decode(json,“UTF-8”);
ObjectMapper jacksonObjectMapper=新建ObjectMapper();//这是Jackson
列出userRolesGUIBeans=jacksonObjectMapper.readValue(
decodedJson,新的TypeReference(){});
//现在我已经填充了我的bean列表。
}

如承诺的那样,请转到并为
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;
        }
    }
}
import java.util.List;
导入org.springframework.web.bind.annotation.PostMapping;
导入org.springframework.web.bind.annotation.RequestBody;
导入org.springframework.web.bind.annotation.RestController;
@RestController
公共类DemoController{
@后映射(“/请求正文”)
公共无效getRequestBody(@RequestBody列表){
用于(个人:列表){
System.out.println(person.name);
}
}
公共静态类人员{
私有字符串名称;
私有字符串phoneNo;
/**
*@返回名称
*/
公共字符串getName(){
返回名称;
 $.ajax({
        type : "post",
        dataType : 'json', 
        url : 'addAdmin',  
        data : JSON.stringify(entries)
 })
@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.
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;
        }
    }
}