Ajax POST Массив объектов в Spring MVC Controller - Многочисленные ошибки - PullRequest
0 голосов
/ 09 мая 2019

Мне нужно передать сформированный JS массив объектов в контроллер Spring MVC. Все имена свойств совпадают.

@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]

Также пробовал это с ModelAttribute и ArrayList,

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

Сейчас ошибок нет, , но список пуст, данные не получены .

Пробовал все - массивы и списки, JSON.stringify(data) или объект данных с data {"entries" : entries}, RequestBody не работает и выдает ошибки UTF; и RequestParam, как указано выше, тоже не работает.

Это слишком сложно для простой задачи.

Ответы [ 3 ]

0 голосов
/ 09 мая 2019

РЕШЕНИЕ

1) Теоретически, если бы я выполнял представление формы (например, $('#myForm').submit()), я мог бы использовать @ModelAttribute, чтобы автоматически связать мою форму с компонентом. Вот что делает @ModelAttribute - он используется для отправки формы. У меня нет настоящей формы; только мои собственные значения.

Я все еще мог «подделать» отправку формы, создав динамическую форму «на лету», но не смог получить отправку формы в массивном поле (например, 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)
 })

Контроллер (обратите внимание, что требуется пользовательская строка только). Затем он использует Джексон для анализа строки вручную, потому что Spring не сделает этого в этом случае. (Spring будет выполнять автоматический анализ, только если вы используете @ModelAttribute привязку формы.)

@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.

}

0 голосов
/ 10 мая 2019

Как и было обещано, перейдите на https://start.spring.io/ и создайте новый проект с одной зависимостью для spring-boot-starter-web.

После этого вы можете создать в своем проекте следующий компонент.

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.

Вы можете открыть Почтальон и сделать запрос POST следующим образом.

enter image description here enter image description here

Эточто печатается в консоли.

enter image description here

Если это работает с Почтальоном, вы можете заставить его работать в JS.Вы просто не поняли как.Вместо того, чтобы соглашаться с тем «обходным путем», который вы нашли, я думаю, вы должны найти правильный способ отправки запроса в JS.Кроме того, некоторое понимание структуры Spring также поможет.В противном случае вы просто будете беспорядочно пробовать что-то вроде @ModelAttribute, никуда не денясь.

0 голосов
/ 09 мая 2019

Вы пытаетесь отправить объект JSON с помощью сообщения. Вы должны использовать @RequestBody аннотацию.

Попробуйте изменить свой метод следующим образом:

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

Таким образом, Spring перехватит Json и преобразует его в Список желаемых объектов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...