Странное поведение JQuery AJAX с параметрами (Spring @ModelAttribute)

Я пытаюсь передать Map‹ String, String> в Spring через Ajax, используя нотацию @ModelAttribute. С клиентом IntelliJ REST мне просто нужно добавить параметр «infos [KEY]» со значением «VALUE», чтобы получить соответствующую пару ключ/значение, заполненную в хэш-карте.

Я пытаюсь воспроизвести такое же поведение с помощью JQuery.

function update()
{
     $.ajax(
          {
            type: "PATCH",
            url: "url",
            dataType: "json",
            data: {"infos[TheAnswer]": "42"},
            success: function(data)
              {
                alert("OK");
              }
          });
}

Но контроллер Spring не может заполнить мою модель. Вот он (но я не должен быть проблемой, потому что, как я уже сказал, клиент IntelliJ REST работает нормально)

public class ExtraInfos implements Serializable
{
    protected HashMap<String, String> infos = new HashMap<String, String>();

    public HashMap<String, String> getInfos()
    {
        return infos;
    }

    public void setInfos(HashMap<String, String> infos)
    {
        this.infos = infos;
    }
}

Вот метод моего контроллера:

@RequestMapping(value = "/{id}", method = RequestMethod.PATCH)
public
@ResponseBody
Contact updateContact(@PathVariable("id") Long id,
                      @ModelAttribute ExtraInfos infos)
{
    return this.service.update(id, infos);
 }

person Community    schedule 17.03.2014    source источник


Ответы (2)


Хорошо, используя этот контроллер

//Просто пример

   @RequestMapping(value = "/test/{id}", method = RequestMethod.POST)
    public @ResponseBody Integer extra(@PathVariable("id") Long id, @RequestBody ExtraInfos extraInfos){
            System.out.println(id);
            System.out.println(extraInfos.getInfos());

            return 1;
        } 

Дело в том, что, как упоминалось ранее, вам нужно отправить объект для ExtraInfos.

Если предположить, что это пример значения ExtraInfos

ExtraInfos = {infos:{"key":"value"}}

Наш маппер создаст с ним объект ExtraInfos.

Выполнение этого вызова ajax (в данном случае для этого картографа).

$.ajax({
    url:"test/23123",
    type:"post",
    contentType: "application/json; charset=utf-8",
    data:JSON.stringify(ExtraInfos)
})

Вывод на консоль:

23123
{key=value}
person Eduardo Quintana    schedule 17.03.2014
comment
Почему минусы - это неправильный ответ? Если это так, то будет приятно стереть его. - person Eduardo Quintana; 18.03.2014
comment
Был не я. Во всяком случае, теперь он отлично работает, событие с методом PUT. Я почти уверен, что попробовал это, когда Шай Элкаям ответил мне, но, вероятно, я все испортил. Спасибо! - person ; 18.03.2014
comment
Yw я пробовал также с PATCH, и это сработало для меня. Если вы хотите по-прежнему использовать PATCH. - person Eduardo Quintana; 18.03.2014
comment
Я сейчас столкнулся с проблемой. Допустим, у меня есть контроллер с @RequestBody ExtraInfos extraInfos и @RequestParam(something) Long something. Какой запрос я должен сделать с JQuery, чтобы указать, что только часть данных закодирована в json? - person ; 24.03.2014
comment
stackoverflow.com/questions/19468572/ - person Eduardo Quintana; 25.03.2014
comment
Кажется, что когда мы используем requestParam spring, привязывает полное тело запроса к этой переменной, поэтому requestParam терпит неудачу, потому что @requestBody потребляет все тело, которое вы можете добавить в POJO extraInfos или отправить как PathVariable - person Eduardo Quintana; 25.03.2014

Строка modelAttribute не получает данные так, как вы их отправили (объект json).

ИЗМЕНИТЬ

Самый простой способ для вас должен заключаться в следующем:

АЯКС:

$.ajax(
          {
            type: "PATCH",
            url: "url",
            dataType: "json",
            data: {TheAnswer: "42"},
            success: function(data)
              {
                alert("OK");
              }
          });

КОНТРОЛЛЕР:

public @ResponseBody Contact updateContact(@PathVariable("id") Long id,
                          @RequestBody ExtraInfos infos){
        }
person Shay Elkayam    schedule 17.03.2014
comment
К сожалению, ни первое, ни второе решение не работает. Хотя второй выглядел привлекательно. - person ; 18.03.2014
comment
Извини. потерять тип: патч также. Я этого не заметил. Я тоже обновил его в своем ответе. - person Shay Elkayam; 18.03.2014
comment
Кроме того, чтобы использовать первый вариант, вы должны отправить все поля объекта ExtraInfos в структуру ajax json. - person Shay Elkayam; 18.03.2014
comment
Если я отбрасываю тип, то запрос становится запросом GET (по умолчанию), а затем сервер выдает 405 Метод не разрешен - person ; 18.03.2014
comment
поэтому используйте type: 'post' как на контроллере, так и на ajax. - person Shay Elkayam; 18.03.2014
comment
Да, но я хочу, чтобы метод был PATCH, так как я что-то обновляю. - person ; 18.03.2014
comment
Поэтому используйте первый метод и добавьте все поля в структуру ajax на стороне javascript. Это не сработало для вас, потому что вы отправили только TheAnswer, а не все поля в классе ExtraInfos - person Shay Elkayam; 18.03.2014
comment
ExtraInfos содержит только одно поле. Попробую еще раз, может ошибся - person ; 18.03.2014
comment
отправьте его как {theAnswer: 42} и используйте @RequestBody - person Shay Elkayam; 18.03.2014
comment
Я отредактировал свой ответ на самое простое решение. скопируйте и вставьте его, я считаю, что это должно работать. - person Shay Elkayam; 18.03.2014
comment
Удалось ли вам заставить его работать с обновлением, которое я опубликовал? - person Shay Elkayam; 18.03.2014
comment
Я не пробовал, потому что ответ Эдуардо сработал. Во всяком случае, я думаю, вы имели в виду contantType вместо dataType нет? В любом случае, спасибо! - person ; 18.03.2014