programing

스프링에서의 오브젝트매퍼 설정

randomtip 2022. 9. 6. 22:04
반응형

스프링에서의 오브젝트매퍼 설정

는 '제목표'를 입니다.objectMapper는, 「」라고 하는 코멘트가 요소만을 으로,@JsonProperty.

그러기 위해 오브젝트 맵을 설정하는 방법에 대해 설명합니다.

여기에 설명된 대로 커스텀오브젝트 맵퍼를 포함했습니다.

, '''가NumbersOfNewEvents아트리뷰트

힌트 있는 사람?잘 부탁드립니다

잭슨 1.8.0 스프링 3.0.5

Custom Object Mapper(커스텀 오브젝트 맵퍼)

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>

Number Of New Events

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에서 동작합니다.

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" />

org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean 1.2 Spring Boot 1.2 릴리즈가 있습니다.org.springframework.http.converter.json.Jackson2ObjectMapperBuilder를 참조해 주세요.

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 Java의 입니다.@Configuration 링크:

@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
    return builder;
}

:

Jackson 2.x와 Spring 3.1.2+에서 사용한 적이 있습니다.

servlet-timeout.xml:

는 " " " 입니다.<beans:beans>뺄 수도 있어요.beansmvc설정에 따라서는, 이러한 요소의 일부에 대응합니다.

    <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.http://au.edu.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;
        }
    }

}

솔루션 1

번째 사용 시 유용합니다.@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);
        });
    }

솔루션 2

물론 아래의 일반적인 접근법도 유효합니다(또한@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));
    }

@EnableWebMvc 사용이 문제가 되는 이유는 무엇입니까?

@EnableWebMvc를 사용하고 .DelegatingWebMvcConfiguration되어 있다WebMvcConfigurationSupport하다

if (jackson2Present) {
    Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json();
    if (this.applicationContext != null) {
        builder.applicationContext(this.applicationContext);
    }
    messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}

, '의 것을 는 죠.ObjectMapper 「」의 으로 하고 .MappingJackson2HttpMessageConverter「」를 하고 있는 @EnableWebMvc.

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>   

커스텀 시리얼라이저를 등록하기 위한 커스텀오브젝트매퍼를 추가하려면 내 답변을 시험해 보세요.

내 경우(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;
    }
}

Custom Object Serializer.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 설정에서 동작합니다.

이 경우 Java 8 JSR-310 JavaTimeModule을 이노블로 만들려면 먼저 메시지컨버터를 spring-web으로 설정해야 합니다.WebMvcConfigurer당신의 안에서@Configurationclass 를 덮어씁니다.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));
}

이와 같이 커스텀 정의도 등록할 수 있습니다.ObjectMapperJava 기반의 Spring 구성으로 되어 있습니다.

스프링 부트 중2.2.x다음과 같이 설정할 필요가 있습니다.

@Bean
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
    return builder.build()
}

코틀린:

@Bean
fun objectMapper(builder: Jackson2ObjectMapperBuilder) = builder.build()

Spring 4 이후에서는, 를 설정할 필요가 없습니다.MappingJacksonHttpMessageConverter를 설정하기만 하면,ObjectMapper.

(설정)MappingJacksonHttpMessageConverter다른 Message Converter가 손실됩니다.)

다음 작업만 하면 됩니다.

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 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);
    }
}

다음으로 컨텍스트컨피규레이션(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>

이거 잘 돼!

언급URL : https://stackoverflow.com/questions/7854030/configuring-objectmapper-in-spring

반응형