Spring에서 ObjectMapper 구성
내 목표는 objectMapper
주석이 달린 요소 만 직렬화 하도록 구성 하는 것입니다 @JsonProperty
.
이를 위해 objectmapper를 구성하는 방법을 설명 하는 이 설명 을 따랐습니다.
여기에 설명 된대로 사용자 정의 objectmapper를 포함했습니다 .
그러나 클래스 NumbersOfNewEvents
가 직렬화 되면 여전히 json의 모든 속성이 포함됩니다.
아무도 힌트가 있습니까? 미리 감사드립니다
Jackson 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));
}
}
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();
}
}
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 대신) Steve Eastwood의 대답이 나를 위해 작동하지 않았습니다. 이 솔루션은 Spring 3.1에서 작동합니다.
스프링 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" />
나는 이것을 Jackson 2.x 및 Spring 3.1.2+에서 사용했습니다.
servlet-context.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
오랜 시간 동안. Spring Boot 1.2 릴리스부터 org.springframework.http.converter.json.Jackson2ObjectMapperBuilder
Java Config 용이 있습니다.
String Boot 구성은 다음과 같이 간단 할 수 있습니다.
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
또는 일부 자바 코드 @Configuration
클래스 :
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
return builder;
}
보다:
- 공식 문서 74.3 Jackson ObjectMapper 사용자 지정
- https://dzone.com/articles/latest-jackson-integration
- Spring 내에서 알려지지 않은 속성을 무시하도록 Jackson을 어떻게 전역 적으로 설정합니까?
- 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>
사용자 지정 serializer를 등록하기 위해 사용자 지정 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;
}
}
<mvc:message-converters>(...)</mvc:message-converters>
내 솔루션에는 XML 구성 ( )이 필요하지 않습니다.
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 4 이상에서는 구성 MappingJacksonHttpMessageConverter
하려는 경우 구성 할 필요가 없습니다 ObjectMapper
.
(구성 MappingJacksonHttpMessageConverter
하면 다른 MessageConverter를 잃게됩니다)
다음을 수행하면됩니다.
public class MyObjectMapper extends ObjectMapper {
private static final long serialVersionUID = 4219938065516862637L;
public MyObjectMapper() {
super();
enable(SerializationFeature.INDENT_OUTPUT);
}
}
그리고 Spring 구성에서 다음 빈을 만듭니다.
@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
Java 기반 Spring 구성에 정의 된 모든 사용자 정의 를 등록 할 수 있습니다.
Spring 3.2.4와 Jackson FasterXML 2.1.1을 사용하고 있습니다.
I have created a custom JacksonObjectMapper that works with explicit annotations for each attribute of the Objects mapped:
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);
}
}
Then this is instantiated in the context-configuration (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>
This works fine!
SOLUTION 1
First working solution (tested) useful especially when using @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
Of course the common approach below works too (also working with @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));
}
Why @EnableWebMvc usage is a problem?
@EnableWebMvc is using DelegatingWebMvcConfiguration
which extends WebMvcConfigurationSupport
which does this:
if (jackson2Present) {
Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json();
if (this.applicationContext != null) {
builder.applicationContext(this.applicationContext);
}
messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}
which means that there's no way of injecting your own ObjectMapper
with the purpose of preparing it to be used for creating the default MappingJackson2HttpMessageConverter
when using @EnableWebMvc.
참고 URL : https://stackoverflow.com/questions/7854030/configuring-objectmapper-in-spring
'Nice programing' 카테고리의 다른 글
웹 사이트 구축 비용을 어떻게 청구합니까? (0) | 2020.10.20 |
---|---|
Javascript는 Java에 비해 얼마나 빠릅니까? (0) | 2020.10.20 |
Java에서 변경 불가능한 클래스를 final로 선언하는 이유는 무엇입니까? (0) | 2020.10.20 |
AngularJS에서 버튼 클릭시 새 탭 열기 (0) | 2020.10.20 |
Java에서 memcpy ()에 해당하는 것이 있습니까? (0) | 2020.10.20 |