Spring REST | MappingJacksonHttpMessageConverter produces invalid JSON

14,693

You're using XStream to serialize XML responses and Jackson JSON to serialize JSON responses. Looking at the JSON output you posted, it seems like there's a circular reference issue at hand. I'm guessing Entity has a list of attributes, each pointing to their respective entity. XStream handles circular references transparently by using XPath, this allows to preserve references when deserializing back to objects. Jackson is able to handle circular references since v1.6, but you need to help it by annotating your serialized entities with @JsonManagedReference and @JsonBackReference. I think Jackson is unique in allowing back references in JSON serialization.

See Jackson's documentation on handling bi-directional references using declarative methods for reference.

Share:
14,693
Sri
Author by

Sri

Make stuff. Build things. - https://srirangan.net

Updated on June 25, 2022

Comments

  • Sri
    Sri almost 2 years

    I've implemented a RESTful web service with Spring. The service responds in XML or JSON based on the Accept header. Here's the context.xml mapping:

      <bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller"/>
      <bean id="xmlMessageConverter"
            class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
        <constructor-arg ref="xstreamMarshaller"/>
        <property name="supportedMediaTypes" value="application/xml"/>
      </bean>
    
      <bean id="jsonHttpMessageConverter"
            class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="prefixJson" value="false"/>
        <property name="supportedMediaTypes" value="application/json"/>
      </bean>
    
      <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
          <util:list id="beanList">
            <ref bean="xmlMessageConverter"/>
            <ref bean="jsonHttpMessageConverter"/>
          </util:list>
        </property>
      </bean>
    

    Here is my controller method:

    @Controller
    @RequestMapping(value = "/entityService")
    class RestfulEntityService {
    
      @Resource
      private EntityService entityService;
    
      @ResponseBody
      @RequestMapping(value = "/getAllEntities", method = RequestMethod.GET)
      public List<Entity> getAllEntities() {
        return entityService.getAllEntities();
      }
    }
    

    The XML response is valid, however, when the client sets the Accept header to application/json, the response is invalid JSON.

    Here is the JSON response sample:

    [{"id":3,"attributes":[{"id":18,"attributeValue":null,"attributeName":"mobile","attributeType":"varchar(40)","entity":{"id":3,"attributes":[{"id":18,"attributeValue":null,"attributeName":"mobile","attributeType":"varchar(40)","entity":{"id":3,"attributes":[{"id":18,"attributeValue":null,"attributeName":"mobile","attributeType":"varchar(40)","entity":{"id":3,"attributes": ..... repeats for a while and then stops..
    
  • Sri
    Sri about 13 years
    Sounds promising.. let me try!