2011-08-22 36 views
6

Tengo problemas para la asignación de un JSON Agregar a un objeto particular de Java para salvarlo por medio de HibernateSpring MVC: @ResponseBody, 415 no admitido Tipo de soporte

encabezados de la llamada Ajax están correctamente ...

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

y el HTTP-Method es POSTAL

Aquí viene la configuración de mi ...

correlación de funciones

Mi Spring MVC se ve así

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

en mi xml contenedor Tengo un ContentNegotiatingViewResolver como esto

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

en mi xml contenedor de la parte de Jackson

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

Tengo

  • Jackson-core-ASL-1.8.5
  • Jackson mapeador-ASL-1.8.5

en mi carpeta/lib

y Jackson trabaja para un caso sencillo como esto

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

cuando lo pruebo con curl

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

No hay problemas, pero si lo prueba con el objeto de hibernación que reciben el mensaje

415 Unsupported Media Type 

cualquier idea.

Respuesta

13

StanMax guiar a mi en la dirección correcta ...

primero tenía que establecer el @JsonManagedReference y @JsonBackReference derecha.Puedo ajustar el ManagedReference al atributo que representa el UNO de la relación UNO-A-Muchos, pero al parecer hay que configurarlo a los muchos atributos (la colección)

ver la descripción aquí http://wiki.fasterxml.com/JacksonFeatureBiDirReferences

@JsonBackReference es la parte de "atrás" de referencia: se omite en la serialización, y re-construida durante la deserialización de referencia hacia adelante.

  • propiedad anotada debe ser del tipo de frijol

El problema en mi caso era que yo no envié información suficiente en mi post JSON para que coincida con los requisitos de Hibernate.

Esto dio como resultado una excepción de que los campos adecuados para crear un objeto Hibernate de mi JSON POST no estaban presentes.

Creé una url de prueba donde creé el mapeador de objetos e intenté deserializar JSON a mano. Esto arroja el mensaje de error correcto.

Me parece que Spring desafortunadamente arroja la excepción 415 "Tipo de soporte no admitido" que es un poco engañosa.

Para el futuro. Pruébelo primero a mano (vea el ejemplo incluido) y luego continúe.

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 

Espero que esto ayude a alguien.

Saludos JS

+0

Esto me salvó totalmente el día ... la semana. ¡Un mensaje de error realmente engañoso! ¿Cómo es esto posible? –

+0

jeje Espero que hayas votado;) –

+0

+1 - truco de eliminación de errores impresionante. – Martin

4

Una cosa que puedes intentar es averiguar si el problema es con el enlace de datos de Jackson (no serializa el objeto de hibernación) u otra cosa. Esto se puede hacer construyendo manualmente ObjectMapper, verificando si 'mapper.serializeValueAsString()' funciona o arroja una excepción.

Hay una gran posibilidad de que tenga que ver con el manejo por parte de Jackson de las propiedades con carga lenta; si es así, puede necesitar usar jackson hibernate module ya que puede manejar detalles específicos de Hibernate.

+0

me sale el mensaje de error '' 'defaultReference': tipo de referencia hacia atrás (java.util.Set) no es compatible con el tipo administrado () '' –

2

Tuve el mismo problema. Después de leer cómo funciona MappingJacksonHttpMessageConverter, me di cuenta de que no lo había inicializado correctamente. por lo que utiliza lo siguiente en mi reposo-servlet.xml y funcionó ..

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