Spring @ResponseBody Json Cyclic Reference - PullRequest
5 голосов
/ 16 марта 2012

Я пытаюсь использовать Spring 3.x @ResponseBody для генерации ответа json / xml, я использую JPA 2.0 ORM, когда есть много-много таблиц отношения ч / б, тогда json вызывает LazyInitializationException

Если я дам "готовую выборку", то это будет циклическая ссылка.

Ответы [ 3 ]

3 голосов
/ 21 марта 2012

Судя по вашим комментариям, просто создайте кастом Serializer.

Ваш JsonSerializer. Вы можете иметь их для каждого типа объекта, который вы пытаетесь сериализовать.

public class MyObjectJsonSerializer extends JsonSerializer<MyObject> {

@Override
public Class<MyObject> handledType() {
    return MyObject.class;
}

@Override
public void serialize(MyObject myObject, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
    jgen.writeStartObject();
    jgen.writeNumberField("id", myObject.getId());
    // whatever else you need
    jgen.writeEndObject();
}

}

Ваш ObjectMapper.

public class MyObjectMapper extends ObjectMapper {

public MyObjectMapper() {
    SimpleModule module = new SimpleModule("My Module", new Version(1, 0, 0, "SNAPSHOT"));
    module.addSerializer(new MyObjectJsonSerializer());

    this.registerModule(module);
}

}

А потом в вашем spring-config.xml.

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
            <property name="objectMapper" ref="myObjectMapper" />
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

<bean id="myObjectMapper" class="com.manne.app.objectmapper.MyObjectMapper" />
3 голосов
/ 10 апреля 2012

Недавно я столкнулся с похожей проблемой: Джексон - сериализация сущностей с двунаправленными связями (избегая циклов)

Таким образом, решение состоит в том, чтобы перейти на Джексон 2.0 и добавить к классам следующееаннотация:

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, 
                  property = "@id")
public class SomeEntityClass ...

Тогда проблема в том, что Spring не работает с Jackson 2.0.Это было решено следующим образом:

<bean id="jacksonMessageConverter"
          class="own.implementation.of.MappingJacksonHttpMessageConverter"/>

<bean class="org.springframework.web.servlet.mvc
             .annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jacksonMessageConverter"/>
            </list>
        </property>
        <property name="requireSession" value="false"/>
    </bean>

И own.implementation.of.MappingJacksonHttpMessageConverter основан на этом:

http://www.jarvana.com/jarvana/view/org/springframework/spring-web/3.0.0.RELEASE/spring-web-3.0.0.RELEASE-sources.jar!/org/springframework/http/converter/json/MappingJacksonHttpMessageConverter.java?format=ok

Но используйте ObjectMapper и другие классы Джексонаот Джексона 2.0 вместо Джексона 1. *

1 голос
/ 18 марта 2012

Звучит так, как будто вы сериализовали объект, управляемый ORM, в JSON, но не инициализировали все дочерние ассоциации, что привело к LazyInitializationException, так как ваш контроллер не имеет дескриптора подключения к БД.2 варианта:

  1. Инициализация всех дочерних ассоциаций объектов в слое DAO
  2. Преобразование управляемого объекта ORM в объект TO и его передачу в контроллер для преобразования в JSON
...