Можно ли использовать @JsonTypeInfo с коллекциями? - PullRequest
4 голосов
/ 19 сентября 2011

Используя Spring 3 и Jackson 1.7.6, я могу сериализовать реализации абстрактного класса и выводить полное имя класса в виде свойства с именем @class.Это прекрасно работает, когда мои Spring-контроллеры возвращают один экземпляр из контроллера, помеченного @ResponseBody.

. При возврате Collection вышеуказанных типов результирующий JSON изменяется в зависимости от того, какой тип сериализуется (поля изкаждый подкласс присутствует), но он не включает свойство @class, которое требуется нашему клиентскому коду.

Как получить подсказку этого типа в сериализованном JSON при возврате коллекции?

//Returns complete with @class=com.package.blah
@RequestMapping("/json/getProduct.json")
public @ResponseBody Product getProduct(Integer id)
{
    return service.getProduct(id);
}

//Does not include @class 
@RequestMapping("/json/getProducts.json")
public @ResponseBody List<Product> getProducts()
{
    return service.getProducts();
}

Ответы [ 3 ]

2 голосов
/ 20 сентября 2011

Вы можете использовать @JsonTypeInfo с POJO, коллекциями и картами, но учтите, что тип объявленных значений коллекций и карт должен иметь аннотацию @JsonTypeInfo (или наследовать) (при использовании аннотации @JsonTypeInfo для каждого класса). Это не будет работать, например, если у вас есть тип, такой как «Коллекция» - в этом случае ответ Диджея будет правильным, так как вы можете принудительно включить опцию «типизация по умолчанию».

Но все должно работать, если у вас есть свойство Collection для сериализации / десериализации, т. Е .:

public class Bean {
    @JsonTypeInfo(....)
    public Collection<Object> listOfObjects; // does work because it's per-property annotation!
    // ... also, applies to value type and not Collection type itself
}

, поскольку это переопределит любой тип значения аннотации @JsonTypeInfo, иначе может иметь

2 голосов
/ 20 сентября 2011

Для этого вам необходимо настроить ObjectMapper.Это не так просто с помощью Spring, поскольку вместо устанавливаемых свойств ObjectMapper имеет вызываемые методы, которые устанавливают его состояние (а затем он сохраняет это как битовую маску).

Если вы используете <mvc:annotation-driven />, вам необходимо заменитьэто с эквивалентной разметкой, которую можно найти в Spring JavaDocs.

Расширить ObjectMapper:

public class ConfigurableObjectMapper extends ObjectMapper
{
    public ConfigurableObjectMapper()
    {
        this.enableDefaultTypingAsProperty(DefaultTyping.JAVA_LANG_OBJECT, JsonTypeInfo.Id.CLASS.getDefaultPropertyName());
    }
}

Затем скажите Spring использовать экземпляр этого класса вместо реализации по умолчанию.

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="order" value="0" />
</bean>

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="webBindingInitializer">
        <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
            <property name="validator" ref="validator" />
        </bean>
    </property>
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
                <property name="objectMapper">
                    <bean class="com.blitzgamesstudios.web.common.json.ConfigurableObjectMapper" />
                </property>
            </bean>
            <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
            <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
            <bean class="org.springframework.http.converter.FormHttpMessageConverter" />
            <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
        </list>
    </property>
</bean>

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
0 голосов
/ 17 сентября 2014

У меня была проблема с java.util.Map, поэтому я сделал что-то вроде:

public interface MyMap extends Map<Long, Product> {}

и

public class MyHashMap extends HashMap<Long, Product> implements MyMap {}

Найденоon: http://jackson -users.ning.com / forum / themes / mapper-not-include-type-information-when-serializing-object-why

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...