mon objectif est de configurer le objectMapper
de manière à ne sérialiser que les éléments annotés avec @JsonProperty
.
Pour ce faire, j'ai suivi cette explication qui explique comment configurer le objectmapper.
J'ai inclus le objectmapper personnalisé comme décrit ici .
Cependant, lorsque la classe NumbersOfNewEvents
est sérialisée, elle contient toujours tous les attributs du fichier json.
Quelqu'un a-t-il un indice? Merci d'avance
Jackson 1.8.0 ressort 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));
}
}
servlet.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();
}
}
JacksonConfiguration
? C'est un moyen automatique de demander à Spring Boot d'utiliser cette classe comme classe de configuration pour Jackson?@EnableWebMvc
? Je doute parce que ... voir dans ma réponse : Pourquoi l'utilisation de @EnableWebMvc est un problème?C'est peut-être parce que j'utilise Spring 3.1 (au lieu de Spring 3.0.5 comme votre question l'a spécifié), mais la réponse de Steve Eastwood n'a pas fonctionné pour moi. Cette solution fonctionne pour Spring 3.1:
Dans votre contexte printemps 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" />
la source
Il y en a
org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean
depuis longtemps. À partir de la version 1.2 de Spring Boot, il existeorg.springframework.http.converter.json.Jackson2ObjectMapperBuilder
pour Java Config.Dans String, la configuration peut être aussi simple que:
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
dans
classpath:application.properties
ou du code Java dans la@Configuration
classe:@Bean public Jackson2ObjectMapperBuilder jacksonBuilder() { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd")); return builder; }
Voir:
la source
Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json()
.J'ai utilisé ceci avec Jackson 2.x et Spring 3.1.2+
servlet-context.xml:
Notez que l'élément racine est
<beans:beans>
, donc vous devrez peut-être supprimerbeans
et ajoutermvc
certains de ces éléments en fonction de votre configuration.<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; } } }
la source
J'ai trouvé la solution maintenant basée sur https://github.com/FasterXML/jackson-module-hibernate
J'ai étendu le mappeur d'objets et ajouté les attributs dans le constructeur hérité.
Ensuite, le nouveau mappeur d'objets est enregistré en tant que bean.
<!-- 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>
la source
ObjectMapper
tant que@Component
et@Primary
. C'est l'approche recommandée dans le Spring Reference Guide et cela a bien fonctionné pour moi.Si vous souhaitez ajouter un ObjectMapper personnalisé pour enregistrer des sérialiseurs personnalisés, essayez ma réponse.
Dans mon cas (Spring 3.2.4 et Jackson 2.3.1), configuration XML pour un sérialiseur personnalisé:
<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>
a été de manière inexpliquée réécrit par défaut par quelque chose.
Cela a fonctionné pour moi:
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; } }
Aucune configuration XML (
<mvc:message-converters>(...)</mvc:message-converters>
) n'est nécessaire dans ma solution.la source
J'utilise Spring 4.1.6 et 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>
cela fonctionne à ma configuration applicationContext.xml
la source
SOLUTION 1
Première solution de travail (testée) utile surtout lors de l'utilisation de @EnableWebMvc:
@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Autowired private ObjectMapper objectMapper;// created elsewhere @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { // this won't add a 2nd MappingJackson2HttpMessageConverter // as the SOLUTION 2 is doing but also might seem complicated converters.stream().filter(c -> c instanceof MappingJackson2HttpMessageConverter).forEach(c -> { // check default included objectMapper._registeredModuleTypes, // e.g. Jdk8Module, JavaTimeModule when creating the ObjectMapper // without Jackson2ObjectMapperBuilder ((MappingJackson2HttpMessageConverter) c).setObjectMapper(this.objectMapper); }); }
SOLUTION 2
Bien sûr, l'approche commune ci-dessous fonctionne également (fonctionne également avec @EnableWebMvc):
@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Autowired private ObjectMapper objectMapper;// created elsewhere @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { // this will add a 2nd MappingJackson2HttpMessageConverter // (additional to the default one) but will work and you // won't lose the default converters as you'll do when overwriting // configureMessageConverters(List<HttpMessageConverter<?>> converters) // // you still have to check default included // objectMapper._registeredModuleTypes, e.g. // Jdk8Module, JavaTimeModule when creating the ObjectMapper // without Jackson2ObjectMapperBuilder converters.add(new MappingJackson2HttpMessageConverter(this.objectMapper)); }
Pourquoi l'utilisation de @EnableWebMvc est-elle un problème?
@EnableWebMvc utilise
DelegatingWebMvcConfiguration
quelle extensionWebMvcConfigurationSupport
fait ceci:if (jackson2Present) { Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json(); if (this.applicationContext != null) { builder.applicationContext(this.applicationContext); } messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build())); }
ce qui signifie qu'il n'y a aucun moyen d'injecter le vôtre
ObjectMapper
dans le but de le préparer à être utilisé pour créer la valeur par défautMappingJackson2HttpMessageConverter
lors de l'utilisation de @EnableWebMvc.la source
Dans Spring Boot,
2.2.x
vous devez le configurer comme ceci:@Bean public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { return builder.build() }
Kotlin:
@Bean fun objectMapper(builder: Jackson2ObjectMapperBuilder) = builder.build()
la source
Au-dessus de Spring 4, il n'est pas nécessaire de configurer
MappingJacksonHttpMessageConverter
si vous avez uniquement l'intention de configurerObjectMapper
.(configurer vous
MappingJacksonHttpMessageConverter
fera perdre un autre MessageConverter)Il vous suffit de faire:
public class MyObjectMapper extends ObjectMapper { private static final long serialVersionUID = 4219938065516862637L; public MyObjectMapper() { super(); enable(SerializationFeature.INDENT_OUTPUT); } }
Et dans votre configuration Spring, créez ce bean:
@Bean public MyObjectMapper myObjectMapper() { return new MyObjectMapper(); }
la source
_halObjectMapper: defined in null
Pour configurer un convertisseur de messages en plain spring-web, dans ce cas pour activer le Java 8 JSR-310 JavaTimeModule, vous devez d'abord implémenter
WebMvcConfigurer
dans votre@Configuration
classe, puis remplacer laconfigureMessageConverters
méthode:@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)); }
De cette manière, vous pouvez enregistrer toute personnalisation définie
ObjectMapper
dans une configuration Spring basée sur Java.la source
extendMessageConverters
, selon la documentation Spring . Mais je n'en ai pas eu besoin, car j'ai juste besoin d'un personnaliséMappingJackson2HttpMessageConverter
.J'utilise Spring 3.2.4 et Jackson FasterXML 2.1.1.
J'ai créé un JacksonObjectMapper personnalisé qui fonctionne avec des annotations explicites pour chaque attribut des objets mappés:
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); } }
Ensuite, ceci est instancié dans la configuration du contexte ( servlet-context.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>
Cela fonctionne très bien!
la source