Spring MVC и отображение Джексона не возвращают корневой элемент в json - PullRequest
3 голосов
/ 01 марта 2012

У меня одна проблема с Spring MVC и его поддержкой json.Я делаю один вызов ajax, чтобы получить некоторые данные, и я хочу получить эти данные в формате json, включая корневое значение.Я также использую аннотации JABX в сущностях, потому что они используются для некоторых REST API.

. Я прочитал, что для получения корневого значения, включенного в Jackson, я должен использовать этот метод:

this.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);

Итак, я создал один объектMapper, который расширяет кодовый блок и выглядит следующим образом:

public class JaxbJacksonObjectMapper extends ObjectMapper {

    public JaxbJacksonObjectMapper() {
        final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();

        this.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
        super.getDeserializationConfig().withAnnotationIntrospector(introspector);

        this.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
        super.getSerializationConfig().withAnnotationIntrospector(introspector);
    }
}

Для Spring, чтобы использовать этот картограф, я настроил следующие строки:

<beans:bean id="customObjectMapper" class="com.test.package.config.JaxbJacksonObjectMapper" />

<beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
    <beans:property name="objectMapper" ref="customObjectMapper" />
</beans:bean>

<beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <beans:property name="messageConverters">
        <beans:list>
            <beans:ref bean="jsonMessageConverter"/>
        </beans:list>
    </beans:property>
</beans:bean>

А мои сущности выглядят так:

@XmlRootElement(name = "collection")
public class Issuers {
    private List<Issuer> issuers;
}

Проблема в том, что когда Spring 3.1 возвращает объект json Issuers в браузер, он не включает корневой элемент collection.

Есть идеи, как решить эту проблему?

Спасибо!

Ответы [ 4 ]

3 голосов
/ 02 июля 2012

Похоже, что метод withAnnotiationIntrospector не устанавливает AnnotiationIntrospector.Вместо этого он возвращает new DeserializationConfig/SerializationConfig объект (с правильным AnnotiationIntrospector).

Итак, моя версия JaxbJacksonObjectMapper:

public class JaxbJacksonObjectMapper extends ObjectMapper {

    public JaxbJacksonObjectMapper() {
        super();

        final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();

        this.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
        this.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRAP_ROOT_VALUE, true);

        this.setDeserializationConfig(this.getDeserializationConfig().withAnnotationIntrospector(introspector));
        this.setSerializationConfig(this.getSerializationConfig().withAnnotationIntrospector(introspector));

    }
}

Теперь он поддерживает @XmlRootElement, @XmlTransient идругой.

0 голосов
/ 06 сентября 2013

Альтернатива этому использованию после одного утверждения:

setAnnotationIntrospector(introspector);

вместо двух следующих утверждений,

super.getDeserializationConfig().setAnnotationIntrospector(introspector);
super.getSerializationConfig().setAnnotationIntrospector(introspector);
0 голосов
/ 02 марта 2012

Кажется, что конфигурация пружины была неправильной. Это не отменяло конвертеры сообщений, поэтому я не взял Mapper, который я написал.

Чтобы переопределить их, правильная конфигурация пружины:

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

Теперь я получаю корневой элемент, но он принимает не имя, указанное в аннотации jabx, а имя класса.

Кажется, что новый метод (withAnnotiationIntrospector) не работает должным образом, или я что-то упустил. Но если использовать устаревшее, я получаю правильное имя корня, определенное в метке JABX.

    public JaxbJacksonObjectMapper() {
    final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();

    this.configure(org.codehaus.jackson.map.SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
    this.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);

    // When using the non deprecated method (withAnnotationIntrospector),
    // there are problems with JAXB/JSON parser so don't use right now

    super.getDeserializationConfig().setAnnotationIntrospector(introspector);
    super.getSerializationConfig().setAnnotationIntrospector(introspector);
}
0 голосов
/ 01 марта 2012

Оберните своих «Эмитентов» в общий объект-держатель.Это то, что я делаю при работе с Джексоном и Спрингом.

class JSONResponse {

    private Object collection;

    public JSONResponse(Object collection) {
        this.collection = collection;
    }
    public Object getCollection() {
        return collection;
    }
}

...

@RequestMappin(...)
@ResponseBody
public Object someHandler(...) {
    ...
    return new JSONResponse(issuers);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...