2011-08-22 14 views
6

Mam problem mapowanie JSON Posta do konkretnego obiektu Java, aby go zapisać poprzez HibernateWiosna MVC: @ResponseBody, 415 nieobsługiwany Typ nośnika

nagłówki wywołania AJAX są prawidłowo ustawione ...

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

i HTTP POST Metoda jest

Nadchodzi moja konfiguracja ...

My Wiosna MVC mapowanie funkcji wygląda następująco

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

w moim pojemnika xml Mam ContentNegotiatingViewResolver jak ten

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

w moim pojemnika xml część dla Jacksona

<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" /> 

Mam

  • Jackson-core-ASL-1.8.5
  • Jackson-mapper-npm-1.8.5

w moim/lib folderu

i Jackson pracuje dla prostego przypadku tak

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) { 
    ... 
} 

kiedy przetestować go z curl

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

Żadnych problemów, ale gdybym go przetestować z obiektem hibernacji pojawia się komunikat

415 Unsupported Media Type 

żadnych pomysłów.

Odpowiedz

13

StanMax prowadzić mój we właściwym kierunku ...

Najpierw musiałem ustawić prawo @JsonManagedReference i @JsonBackReference.Ustawić ManagedReference do atrybutu, który reprezentuje ONE z relacji jeden-do-wielu, ale widocznie trzeba ustawić go do wielu atrybutu z (zbiór)

patrz opis tutaj http://wiki.fasterxml.com/JacksonFeatureBiDirReferences

@JsonBackReference jest „do tyłu” część odniesienia: będzie pominięty serializacji i ponownie wykonana w deserializacji odniesienia przyszłość.

  • Adnotacje nieruchomość musi być fasoli typu

Problem w moim przypadku było to, że nie wysłał wystarczających informacji w moim JSON POST do wymagań hibernacji.

Powodowało to wyjątek, że nie znaleziono właściwych pól do utworzenia obiektu Hibernacja poza moim postem JSON.

Utworzyłem testowy URL, w którym sam stworzyłem program obiektowy i próbowałem rozszyfrować JSON ręcznie. To spowoduje wyświetlenie odpowiedniego komunikatu o błędzie.

Wydaje mi się, że Spring niestety rzuca wyjątek 415 "Nieobsługiwany typ nośnika", co jest nieco mylące.

Więc na przyszłość. Wypróbuj najpierw ręcznie (patrz przykład) i kontynuuj.

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 

Mam nadzieję, że to komuś pomaga.

Pozdrowienia JS

+0

To całkowicie uratowało mój dzień ... tydzień. Naprawdę przesłanie komunikatu o błędzie! Jak to jest możliwe? –

+0

hehe Mam nadzieję, że wznowiłeś;) –

+0

+1 - niesamowita sztuczka debugowania. – Martin

4

Jedna rzecz, którą możesz spróbować, to dowiedzieć się, czy problem dotyczy powiązania danych Jacksona (nie można serializować obiektu hibernacji), czy czegoś innego. Można to zrobić, ręcznie konstruując ObjectMapper, sprawdzając, czy działa funkcja 'mapper.serializeValueAsString()' lub zgłasza wyjątek.

Istnieje spora szansa, że ​​ma to związek z obsługą Jacksona z leniwie załadowanymi właściwościami; jeśli tak, być może będziesz musiał użyć jackson hibernate module, ponieważ może on obsługiwać szczegóły specyficzne dla Hibernacji.

+0

pojawia się komunikat o błędzie '' „”: defaultReference typ odesłanie (java.util.Set) niekompatybilnego z zarządzanym typu () '' –

2

Miałem ten sam problem. Po przeczytaniu, jak działa MappingJacksonHttpMessageConverter, zdałem sobie sprawę, że nie zainicjowałem go poprawnie. Więc użyłem następujących w moim Rest-servlet.xml i to działało ..

<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" /> 
Powiązane problemy