Настройка ObjectMapper весной
моя цель-настроить objectMapper
в том смысле, что он только serialises элемент, который аннотируются @JsonProperty
.
для этого я последовал этому объяснение в котором говорится, как настроить objectmapper.
Я включил пользовательский objectmapper, как описано здесь.
однако, когда класс NumbersOfNewEvents
сериализуется, он по-прежнему содержит все атрибуты в json.
у кого-нибудь есть намек? Заранее спасибо
Джексон 1.8.0 весна 3.0.5
CustomObjectMapper
public class CompanyObjectMapper extends ObjectMapper {
public CompanyObjectMapper() {
super();
setVisibilityChecker(getSerializationConfig()
.getDefaultVisibilityChecker()
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE)
.withFieldVisibility(JsonAutoDetect.Visibility.NONE)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.DEFAULT));
}
}
сервлет.в XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="de.Company.backend.web" />
<mvc:annotation-driven />
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="jacksonObjectMapper" />
</bean>
</list>
</property>
</bean>
<bean id="jacksonObjectMapper" class="de.Company.backend.web.CompanyObjectMapper" />
</beans>
NumbersOfNewEvents
public class NumbersOfNewEvents implements StatusAttribute {
public Integer newAccepts;
public Integer openRequests;
public NumbersOfNewEvents() {
super();
}
}
10 ответов
используя Spring Boot (1.2.4) и Jackson (2.4.6), для меня работала следующая конфигурация на основе аннотаций.
@Configuration
public class JacksonConfiguration {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
return mapper;
}
}
это может быть потому, что я использую Spring 3.1 (вместо Spring 3.0.5, как указано в вашем вопросе), но ответ Стива Иствуда не сработал для меня. Это решение работает для Spring 3.1:
в контексте spring xml:
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="jacksonObjectMapper" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="jacksonObjectMapper" class="de.Company.backend.web.CompanyObjectMapper" />
я использовал это с Джексоном 2.x и весной 3.1.2+
сервлет-контексте.XML-код:
обратите внимание, что корневой элемент <beans:beans>
, поэтому вам может потребоваться удалить beans
и добавить mvc
в некоторых из этих элементов в зависимости от вашего установка.
<annotation-driven>
<message-converters>
<beans:bean
class="org.springframework.http.converter.StringHttpMessageConverter" />
<beans:bean
class="org.springframework.http.converter.ResourceHttpMessageConverter" />
<beans:bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<beans:property name="objectMapper" ref="jacksonObjectMapper" />
</beans:bean>
</message-converters>
</annotation-driven>
<beans:bean id="jacksonObjectMapper"
class="au.edu.unimelb.atcom.transfer.json.mappers.JSONMapper" />
au.edu.unimelb.atcom.transfer.json.mappers.JSONMapper.java:
public class JSONMapper extends ObjectMapper {
public JSONMapper() {
SimpleModule module = new SimpleModule("JSONModule", new Version(2, 0, 0, null, null, null));
module.addSerializer(Date.class, new DateSerializer());
module.addDeserializer(Date.class, new DateDeserializer());
// Add more here ...
registerModule(module);
}
}
DateSerializer.java:
public class DateSerializer extends StdSerializer<Date> {
public DateSerializer() {
super(Date.class);
}
@Override
public void serialize(Date date, JsonGenerator json,
SerializerProvider provider) throws IOException,
JsonGenerationException {
// The client side will handle presentation, we just want it accurate
DateFormat df = StdDateFormat.getBlueprintISO8601Format();
String out = df.format(date);
json.writeString(out);
}
}
DateDeserializer.java:
public class DateDeserializer extends StdDeserializer<Date> {
public DateDeserializer() {
super(Date.class);
}
@Override
public Date deserialize(JsonParser json, DeserializationContext context)
throws IOException, JsonProcessingException {
try {
DateFormat df = StdDateFormat.getBlueprintISO8601Format();
return df.parse(json.getText());
} catch (ParseException e) {
return null;
}
}
}
здесь org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean
в течение длительного времени. Начиная с 1.2 выпуска Spring Boot есть org.springframework.http.converter.json.Jackson2ObjectMapperBuilder
для конфигурации Java.
в конфигурации загрузки строки может быть так же просто, как:
spring.jackson.deserialization.<feature_name>=true|false
spring.jackson.generator.<feature_name>=true|false
spring.jackson.mapper.<feature_name>=true|false
spring.jackson.parser.<feature_name>=true|false
spring.jackson.serialization.<feature_name>=true|false
spring.jackson.default-property-inclusion=always|non_null|non_absent|non_default|non_empty
на classpath:application.properties
или некоторый код Java в @Configuration
класс:
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
return builder;
}
посмотреть:
- официальные документы 74.3 настройка Джексона ObjectMapper
- https://dzone.com/articles/latest-jackson-integration
- как вы глобально установить Джексон игнорировать неизвестные свойства в течение весны?
- http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.html
Я нашел решение теперь на основе https://github.com/FasterXML/jackson-module-hibernate
я расширил сопоставитель объектов и добавил атрибуты в унаследованный конструктор.
затем новый сопоставитель объектов регистрируется как Боб.
<!-- https://github.com/FasterXML/jackson-module-hibernate -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<array>
<bean id="jsonConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper">
<bean class="de.company.backend.spring.PtxObjectMapper"/>
</property>
</bean>
</array>
</property>
</bean>
если вы хотите добавить пользовательский ObjectMapper для регистрации пользовательских сериализаторов, попробуйте мой ответ.
в моем случае (Spring 3.2.4 и Jackson 2.3.1), конфигурация XML для пользовательского сериализатора:
<mvc:annotation-driven>
<mvc:message-converters register-defaults="false">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="serializers">
<array>
<bean class="com.example.business.serializer.json.CustomObjectSerializer"/>
</array>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
был необъяснимым образом перезаписан обратно по умолчанию чем-то.
это сработало для меня:
CustomObject.java
@JsonSerialize(using = CustomObjectSerializer.class)
public class CustomObject {
private Long value;
public Long getValue() {
return value;
}
public void setValue(Long value) {
this.value = value;
}
}
CustomObjectSerializer.java
public class CustomObjectSerializer extends JsonSerializer<CustomObject> {
@Override
public void serialize(CustomObject value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,JsonProcessingException {
jgen.writeStartObject();
jgen.writeNumberField("y", value.getValue());
jgen.writeEndObject();
}
@Override
public Class<CustomObject> handledType() {
return CustomObject.class;
}
}
нет конфигурации XML (<mvc:message-converters>(...)</mvc:message-converters>
) является необходимо в моем решении.
Я использую Spring 4.1.6 и Jackson FasterXML 2.1.4.
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<!-- 设置不输出null字段-->
<property name="serializationInclusion" value="NON_NULL"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
это работает в моем applicationContext.XML-файле конфигурации
Я использую Spring 3.2.4 и Jackson FasterXML 2.1.1.
Я создал пользовательские JacksonObjectMapper это работает с явными аннотациями для каждого атрибута сопоставленных объектов:
package com.test;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
public class MyJaxbJacksonObjectMapper extends ObjectMapper {
public MyJaxbJacksonObjectMapper() {
this.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
.setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.ANY)
.setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE);
this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
}
}
тогда это создается в конфигурации контекста (сервлет-контексте.в XML):
<mvc:annotation-driven>
<mvc:message-converters>
<beans:bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<beans:property name="objectMapper">
<beans:bean class="com.test.MyJaxbJacksonObjectMapper" />
</beans:property>
</beans:bean>
</mvc:message-converters>
</mvc:annotation-driven>
это прекрасно работает!
над весной 4, никакая потребность установить MappingJacksonHttpMessageConverter
Если вы только собираетесь настроить ObjectMapper
.
(настройки MappingJacksonHttpMessageConverter
приведет к потере другого MessageConverter)
нужно сделать:
public class MyObjectMapper extends ObjectMapper {
private static final long serialVersionUID = 4219938065516862637L;
public MyObjectMapper() {
super();
enable(SerializationFeature.INDENT_OUTPUT);
}
}
и в вашей весенней конфигурации создайте этот боб:
@Bean
public MyObjectMapper myObjectMapper() {
return new MyObjectMapper();
}
чтобы настроить конвертер сообщений в простой spring-web, в этом случае, чтобы включить Java 8 JSR-310 JavaTimeModule, вам сначала нужно реализовать WebMvcConfigurer
в своем @Configuration
класс, а затем переопределить configureMessageConverters
способ:
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().modules(new JavaTimeModule(), new Jdk8Module()).build()
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
converters.add(new MappingJackson2HttpMessageConverter(objectMapper));
}
как это вы можете зарегистрировать пользовательский ObjectMapper
в конфигурации Spring на основе Java.