Объект Json и контроллер Spring запрос, отправленный клиентом, был синтаксически неверным (неверный запрос)

1

Я хочу поделиться следующим опытом, который занял меня около двух дней, чтобы исправить это: Инструменты: Spring MVC 3.2.3, Roo 1.2.4, Java 7.

Я попытался передать объект Json своему контроллеру следующим образом:

.js файл

    var params= { 
        "eItemId" : p1,
        "eItemCode" : p2, 
        "eItemPartNbr" : p3, 
        "eItemDesc" : p4,
        "uomItemSlctId" : p5,
        "eForAnyCompany" : flag 
};

$.ajax({
    type: "POST",
    url: "/item/saveitem",
    contentType: "application/json",
    dataType: "json",
    data: JSON.stringify(params),
    cache: false,.....

Я успешно адаптировал сигнатуру метода контроллера без успеха, и, наконец, я сохраняю ее просто, начиная с самого начала:

    @RequestMapping(value="/saveitem", method = RequestMethod.POST)
public @ResponseBody Map<String, String> saveItem(@RequestBody ItemFormBean itemToEdit) {..}

Часто сообщение об ошибке было:

запрос, отправленный клиентом, был синтаксически неправильным (неверный запрос): Bad Request 400

Чтобы понять, что случилось, мне пришлось снизить уровень журнала, чтобы понять проблему, и я обнаружил:

DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - разрешение исключения из обработчика [public java.util.Map com.jarbits.quo.web.ItemController.saveItem(com.company.ItemFormBean, org.springframework. validation.BindingResult)]: org.springframework.http.converter.HttpMessageNotReadableException: не удалось прочитать JSON: нераспознанное поле "eItemId" (класс com.company.ItemFormBean), не помеченное как невежественное (6 известных свойств: "eitemId", "eitemPartNbr "eitemCode", "eforAnyCompany", "eitemDesc", "uomItemSlctId"])

Боб, который отображает объект Json:

@RooJavaBean
public class ItemFormBean {
    @NotNull
    private Long eItemId;
    @Size(min=3, max=30) 
    private String eItemCode;
    @Size(min=3, max=30)
    private String eItemPartNbr;
    @NotNull
    private String eItemDesc;
    @NotNull
    private Long uomItemSlctId;
    private boolean eForAnyCompany;
}

Затем результат..


Здесь результаты. Итак, описание объекта Json корректно основано на определении bean-компонента, однако контроллер ожидал получить:

"eitemId", "eitemPartNbr", "eitemCode", "eforAnyCompany", "eitemDesc", "uomItemSlctId",

вместо:

"eitemId", "eitemPartNbr", "eitemCode", "eforAnyCompany", "eitemDesc", "uomItemSlctId",

Кроме того, я хотел бы упомянуть, что у меня есть следующий параметр в файле webmvc-config.xml.

    <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
    <property name="favorParameter" value="false" />
    <property name="ignoreAcceptHeader" value="false" />
    <property name="mediaTypes" >
        <value>
            atom=application/atom+xml
            html=text/html
            json=application/json
            *=*/*
        </value>
    </property>
</bean>

Это потому, что @ResponseBody не возвращал результаты объектов json.

@Emrakul, @Humdinger Я сделал тест с понижением Jackson 2.0 следующим образом:

com.fasterxml.jackson.core
jackson-annotations 2.4.1 to 2.3.3
jackson-core 2.4.1.1 to 2.3.4
jackson-databind 2.4.1.3 to 2.3.4

У меня точно такой же недостаток.

Как вы сказали, это недостаток с картой Джексона. Не могли бы вы поделиться своими мыслями?

Надеюсь, этот недостаток может помочь другим.

  • 0
    Это хорошо, но есть несколько вещей, которые вы можете сделать, чтобы улучшить его. Когда вы отвечаете на вопросы, пожалуйста, отправьте ответ на свой вопрос с информацией в нем. Затем убедитесь, что ваш вопрос стоит в одиночестве и выглядит хорошо сам по себе. Таким образом, кто-то, кто не знает, что вы сами ответили на вопрос, подумал бы, что и вопрос, и ответ хороши. Спасибо за распространение ваших знаний!
  • 0
    Похоже, это на самом деле является дефектом. Вы пытались изменить json на «плохие» версии в нижнем регистре, просто чтобы посмотреть, что происходит?
Показать ещё 2 комментария
Теги:
spring
spring-mvc

2 ответа

0

Спасибо @Sotirios Delimanolis, это право, однако дефект - это что-то необычное, здравый смысл говорит, что ожидаемое - это просто иметь первую столицу после "получить"... Я имел в виду, getXzzzz, где zzz может быть капиталом или незначительным, а Json должны следовать одному и тому же смыслу.

Правильно, сеттеры и геттер находятся в файлах.aj, это потому, что поддерживается каркасом Roo (@RooJavaBean).

0

Единственный способ, которым я смог воспроизвести вашу проблему, был

public class ItemFormBean {
    private String eItemCode;
    public String getEItemCode() {
        return eItemCode;
    }
    public void setEItemCode(String eItemCode) {
        this.eItemCode = eItemCode;
    }
}

с

{ ..., "eItemCode" : "asd", ... }

который дает

Unrecognized field "eItemCode" (ItemFormBean) (6 known properties: ..., "eitemCode", ...])

Джексон по умолчанию использует ваши геттеры для определения имен свойств. Он делает это, чтобы избавиться от get или is префиксом и lowercasing всех ведущих символов капитала.

Таким образом, getEItemCode превратится в eitemCode. И то, что он ожидает от JSON.

Если вы хотите, вы можете установить его явно, аннотируя один из getter, setter или field с помощью @JsonProperty("eItemCode").

  • 0
    Спасибо @Sotirios Delimanolis , это верно, однако дефект является чем-то необычным, здравый смысл говорит, что ожидается только первая заглавная буква после слова "get" ... Я имел в виду, getXzzzz, где zzz может быть заглавной или незначительной, и Json следует придерживаться того же смысла. Правильно, сеттеры и геттеры находятся в файлах .aj, это потому, что поддержка фреймворка Roo (@RooJavaBean).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню