Spring MVC: @ResponseBody, 415 неподдерживаемых типов носителей - PullRequest
6 голосов
/ 22 августа 2011

У меня проблемы с отображением JSON Post на конкретный Java-объект, чтобы сохранить его через Hibernate

Заголовки вызова Ajax установлены правильно ...

Accept          application/json
Content-Type    application/json; charset=UTF-8

и HTTP-метод: POST

Вот идет моя конфигурация ...

Отображение моей функции Spring MVC выглядит следующим образом

@RequestMapping(value = {"/save.json"},method = RequestMethod.POST)
public ModelMap save(@RequestBody Seizure seizureObj,Model model) {
   ...
}

в моем контейнере xml у меня есть ContentNegotiatingViewResolver вот так

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="mediaTypes">
        <map>
            <entry key="html" value="text/html" />
            <entry key="json" value="application/json" />
        </map>
    </property>
    <property name="viewResolvers">
        <list>
            <bean id="viewResolver"
                class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/WEB-INF/assets/" />
                <property name="suffix" value=".jsp" />
            </bean>
        </list>
    </property>
    <property name="defaultViews">
        <list>
            <bean
                class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
                <property name="prefixJson" value="false" />
                <property name="objectMapper" ref="jacksonObjectMapper" />
            </bean>
        </list>
    </property>
</bean>

в моем контейнере xml часть для Джексона

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapterConfigurer"
    init-method="init">

    <property name="messageConverters">
        <list>
            <bean id="marshallingHttpMessageConverter"
                class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"
          >
          <property name="objectMapper" ref="jacksonObjectMapper" />
          </bean>
        </list>
    </property>
</bean> 

<bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" /> 

у меня

  • ДЖЕКСОН-ядро-ASL-1.8.5
  • ДЖЕКСОН-картограф-ASL-1.8.5

в моей папке / lib

и Джексон работает для простого случая, подобного этому

public class Simple {
  private int id;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }   
}

@RequestMapping(value = {"/saveSimple.json"},method = RequestMethod.POST)
public ModelMap save(@RequestBody Simple simple,Model model) {
   ...
}

когда я проверяю его с помощью curl

 curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":1}'  http://<URL>/saveSimple.json

Нет проблем, но если я проверю его с помощью объекта Hibernate, я получу сообщение

415 Unsupported Media Type

любые идеи.

Ответы [ 4 ]

13 голосов
/ 25 августа 2011

StanMax ведет меня в правильном направлении ...

Сначала я должен был установить @JsonManagedReference и @JsonBackReference правильно. Я установил для ManagedReference атрибут, который представляет ONE отношения ONE-to-MANY , но, очевидно, вы должны установить для него атрибут MANY (коллекция)

см. Описание здесь http://wiki.fasterxml.com/JacksonFeatureBiDirReferences

@ JsonBackReference является «обратной» частью ссылки: она будет исключена из сериализации и перестроена во время десериализации прямой ссылки.

  • Аннотированное свойство должно быть типа боба

Проблема в моем случае заключалась в том, что я не отправил в JSON POST информацию, достаточную для соответствия требованиям Hibernate.

Это привело к исключению, что соответствующие поля для создания объекта Hibernate из моего JSON POST отсутствовали.

Я создал тестовый URL, где я сам создал Object mapper и попытался десериализовать JSON вручную. Это выдает правильное сообщение об ошибке.

Мне кажется, что Spring, к сожалению, генерирует исключение 415 "Unsupported Media Type", которое немного вводит в заблуждение.

Так что на будущее. Сначала попробуйте вручную (см. Пример), а затем продолжайте.

 ModelMap map = new ModelMap();
 logger.info("HibernateAware");
 HibernateAwareObjectMapper mapper = new HibernateAwareObjectMapper();
 String jsonInput = 
 "{" +
   "\"id\":\"1\"," +
   "\"matCountry\":{" +
     "\"id\":\"1\"" +
   "}" +
 "}";
 Seizure seizure = mapper.readValue(jsonInput, Seizure.class); // this line throw the exception

Надеюсь, это кому-нибудь поможет.

С уважением JS

4 голосов
/ 23 августа 2011

Одна вещь, которую вы можете попробовать, - это выяснить, связана ли проблема с привязкой данных Джексона (не удается сериализовать объект гибернации) или с чем-то еще.Это можно сделать, вручную создав ObjectMapper, проверив, работает ли 'mapper.serializeValueAsString ()' или генерирует ли исключение.

Есть большая вероятность, что это связано с обработкой Джексоном лениво загруженных свойств;если это так, вам может понадобиться модуль гибернации Джексона , поскольку он может обрабатывать специфичные для Hibernate детали.

2 голосов
/ 28 января 2012

У меня была такая же проблема.Прочитав, как работает MappingJacksonHttpMessageConverter, я понял, что неправильно его инициализировал.Поэтому я использовал следующее в моем rest-servlet.xml, и это сработало ..

<bean id="jsonHttpMessageConverter"  class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json" />
        </map>
    </property>

    <property name="defaultViews">
        <list>
            <bean
                class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
                <property name="objectMapper">
                    <ref bean="JacksonObjectMapper" />
                </property>
            </bean>
        </list>
    </property>
    <property name="favorPathExtension" value="false" />
    <property name="favorParameter" value="true" />
    <property name="useNotAcceptableStatusCode" value="true" />
</bean>

<bean id="JacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
0 голосов
/ 07 марта 2019

У меня была похожая проблема, связанная с тем, что у одного из моих классов была карта с не примитивным типом ключа.Я смог @JsonIgnore в этом поле, чтобы обойти проблему.

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