programing

스프링 부트에서의 Jackson Object Mapper의 Camel 설정 방법

fastcode 2023. 3. 11. 09:34
반응형

스프링 부트에서의 Jackson Object Mapper의 Camel 설정 방법

Jackson을 사용하여 Camel 루트로 JSON과 주고받는 POJO의 시리얼화 및 시리얼화를 시도하고 있습니다.이들 중 일부는 Java 8 LocalDate 필드를 가지고 있으며, 정수의 배열이 아닌 YYY-MM-DD 문자열로 시리얼화하기를 원합니다.

Spring Boot 어플리케이션에서는 Java Configuration만 사용하기 때문에 XML Camel Configuration은 사용하지 않습니다.

종속성에 추가하여 시스템의 다른 부품에서 사용하고 있는 원하는 작업을 수행하는 Object Mapper를 성공적으로 만들었습니다.

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

어플리케이션 구성에는 다음과 같은 이점이 있습니다.

@Bean
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
    return builder
            .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .build();
}

발신 REST 루트의 예:

@Component
public class MyRouteBuilder extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        restConfiguration().component("servlet").contextPath("/mycontext")
                .port(8080).bindingMode(RestBindingMode.json);

        rest("/myendpoint)
                .get()
                .route()
                .to("bean:myService?method=myMethod()");
    }
}

착신 메시지루트의 예:

@Component
public class MyRouteBuilder extends RouteBuilder {

    @Autowired
    private MyBean myBean;

    @Override
    public void configure() {
        from(uri)
                .unmarshal().json(JsonLibrary.Jackson)
                .bean(myBean);
    }
}

단,으로는 Camel은 독자적인 에 Camel이 ObjectMapper를 사용하는 .Jackson2ObjectMapperBuilder이 된 " " " " " " 가 자동으로 추가됩니다.WRITE_DATES_AS_TIMESTAMPS특징.Camel JSON 매뉴얼은 읽었지만 스프링 구성을 사용하여 커스텀 DataFormat을 추가하는 방법 또는 모든 유형에 글로벌 커스터마이즈를 적용하는 방법은 나와 있지 않습니다.

Spring Boot Java 설정만 사용하여 Camel에게 Object Mapper를 사용하도록 지시하려면 어떻게 해야 합니까?

Spring Boot에서는 오브젝트 매퍼 자동검출이 지원되었습니다.이 속성을 설정하기만 하면 됩니다.

camel.dataformat.json-jackson.auto-discover-object-mapper=true

true로 설정하면 Jackson은 레지스트리에서 objectMapper를 검색합니다.

문서: https://camel.apache.org/components/latest/dataformats/json-jackson-dataformat.html#_spring_boot_auto_configuration

로그:

INFO o.a.c.impl.engine.AbstractCamelContext   : Apache Camel 3.3.0 (CamelContext: camel-1) is starting
INFO o.a.c.c.jackson.JacksonDataFormat        : Found single ObjectMapper in Registry to use: com.fasterxml.jackson.databind.ObjectMapper@20a1b3ae
WARN o.a.c.c.jackson.JacksonDataFormat        : The objectMapper was already found in the registry, no customizations will be applied

란 단지 에 있는 다른 모든 이 있음을).camel.dataformat.json-jackson.*) (무시

업데이트 17.08.2022

'Camel' 이후 새로운 3.15.0 성질을

camel.dataformat.jackson.auto-discover-object-mapper=true

나는 카멜 코드를 통해 해결책을 찾았다.따라서 원하는 기능을 수행하지만 문서화되어 있지 않고 지원되지 않을 수 있기 때문에 향후 버전의 Camel에서는 작동하지 않을 수 있습니다.

할 은 스프링 내 구성 콩을 이다.ObjectMapper[ ] :

@Bean(name = "json-jackson")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public JacksonDataFormat jacksonDataFormat(ObjectMapper objectMapper) {
    return new JacksonDataFormat(objectMapper, HashMap.class);
}

주의할 점은 다음과 같습니다.

  • 에 대한 생성자가 없습니다.JacksonDataFormat은 an an가 하다.ObjectMapper얄팍한 타입이 아닌.에서는 " " " 입니다.HashMap.class되지 않을 때 unmarshal을 합니다.마법에 의해, 이것은 모든 POJO 타입의 마크를 해제하는 것에 익숙해진 것 같습니다. 를 해야 .ObjectMapper그 안에 있어요.
  • 카멜은 콩 레지스트리에서 "json-jackson"이라고 불리는 콩을 검색하기 위해 스프링빈을 설정하면 카멜은 새로운 콩을 만들지 않고 대신 내 콩을 사용하게 됩니다.
  • 는 콩으로 .SCOPE_PROTOTYPE DSL은 "REST DSL"의 인스턴스를 되기 때문입니다.DataFormatCAMEL-7880」을 참조해 주세요.

JacksonDataFormat원하는 기능을 활성화/비활성화한 다음 해당 인스턴스를 Camel 경로에서 사용합니다.

 .unmarshal(myInstanceGoesHere).

는 ''를 사용할 때 합니다.marshal 「」, 「어댑터」를 사용할 수 .unmarshal:

CamelContext ctx = new DefaultCamelContext();
JacksonDataFormat df = new JacksonDataFormat();

df.setModuleClassNames("com.fasterxml.jackson.datatype.jsr310.JavaTimeModule");

ctx.addRoutes(
    new RouteBuilder() {
      @Override
      public void configure() {
        from("direct:start").marshal(df).log("Out");
      }
    });

스프링과 카멜 2.18.1을 사용하여 다음과 같은 종속성을 추가함으로써 동일한 결과를 얻을 수 있었습니다.

<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-parameter-names</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.6.1</version>
</dependency>

a a a...CamelContextConfiguration, 자동 , " " "JacksonDataFormat하려면 , classpath 를 사용합니다.

@Configuration
public class CamelContextConfig implements CamelContextConfiguration {

    @Autowired
    public JacksonDataFormat jacksonDataFormat;

    @Override
    public void beforeApplicationStart(CamelContext camelContext) {
    }

    @Override
    public void afterApplicationStart(CamelContext camelContext) {
        jacksonDataFormat
            .getObjectMapper()
            .findAndRegisterModules()
            .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    }
}

나는 pom에 잭슨 의존증을 포함시킴으로써 해결했다.

<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-jackson-starter</artifactId>
  <version>${camel.version}</version>
</dependency>

Jackson Data Format을 루트 구성에 추가하는 것만으로 끝납니다.

public void configure() throws Exception {
    JacksonDataFormat jsonDf = new JacksonDataFormat(Card.class);
    jsonDf.setPrettyPrint(true);

    from("direct:endpoint")
    .marshal(jsonDf)
    .convertBodyTo(String.class)
    .....
}

지금까지는 @david-edwards의 제안만이 효과가 있었습니다.처음에 데이터 형식 bean을 정의했는데 ID는 "json-jackson"입니다.

<bean id="json-jackson" class="com.mydomain.JacksonDataFormatExt" />

그런 다음 형식 클래스:

public class JacksonDataFormatExt extends JacksonDataFormat{

    public JacksonDataFormatExt(){
        super();
        setPrettyPrint(true);
        setEnableFeatures(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS.name());
        SimpleModule s = new SimpleModule();
        s.addSerializer(CustomEnum.class, new CustomEnumSerializer());
        addModule(s);
    }
}

또한 CustomEnumSerializer 클래스:

public class CustomEnumSerializer extends JsonSerializer<CustomEnum> {

    @Override
    public void serialize(CustomEnumvalue, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        String stringValue = value.getNlsText();
        if(stringValue != null && !stringValue.isEmpty() && !stringValue.equals("null")) {
            jgen.writeString(stringValue);
        } else {
            jgen.writeNull();
        }
    }
}

Object Mapper for Camel을 사용하여 Object 할 수 .org.apache.camel:camel-jackson-starter:2.20.0

Spring 응용 프로그램 속성을 통해 구성하기 위한 유용한 ObjectMapper 속성 중 일부를 표시합니다.WRITE_DATS_AS_예를 들어 TIMESTAMPS는 application.yaml 또는 application.properties 파일에서 바로 설정할 수 있습니다.

자세한 내용은 JacksonDataFormatConfiguration 클래스를 참조하십시오.

또한 Mixins를 사용해야 했기 때문에 Spring의 Object Mapper를 사용하도록 Camel을 설정해야 했습니다.결국 이렇게 됐어요.

컨피규레이션빈:

@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
    return new Jackson2ObjectMapperBuilderCustomizer() {
        @Override
        public void customize(Jackson2ObjectMapperBuilder builder) {
            builder.mixIn(Person.class, PersonMixin.class);
        }
    }
}

application.syslogl:

camel:
  dataformat:
    json-jackson:
      disable-features: WRITE_DATES_AS_TIMESTAMPS
      object-mapper: jacksonObjectMapper

서 ★★★★★jacksonObjectMapper "Jackson2ObjectMapperBuilder" 에 빈 입니다.

2.17 버전에 삽입된 수정 프로그램의 사용법을 궁금해 하는 사람이 있다면..다음 xml 구성을 사용하여 작업을 수행했습니다.

 <camel:camelContext id="defaultCamelContext">
       .....
        <camel:dataFormats>
            <camel:json id="json" library="Jackson"  objectMapper="myObjectMapper"/>
        </camel:dataFormats>

 </camel:camelContext>

..myObjectMapper는 ObjectMapper 유형의 스프링빈 이름입니다.

이쪽이 나에게 도움이 되는 것 (Camel 2.2.0)

    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
        <version>2.12.5</version>
    </dependency>

REST 구성

            restConfiguration().dataFormatProperty("moduleClassNames", "com.fasterxml.jackson.datatype.jsr310.JavaTimeModule")
                               .dataFormatProperty("disableFeatures", "WRITE_DATES_AS_TIMESTAMPS")

만약 카멜이 당신에게 문제를 준다면, 저는 콩을 직접 사용하는 것으로 돌아갈 것입니다.

  1. Marshalling 및 Unmarshalling을 수행하고 사전 설정된 Object Mapper를 자동으로 연결할 수 있는 작은 Json 유틸리티를 만듭니다.

  2. 카멜과 스프링빈의 멋진 통합을 통해 유틸리티에 전화를 걸어 메시지를 전환하십시오. 예를 들어 다음과 같습니다.

         from(uri)
            .unmarshal().json(JsonLibrary.Jackson)
            .beanRef("jsonUtil", "unmarshal")
            .bean(myBean);
    

나는 어떤 예도 제대로 작동하지 않았다.이것이 해결 방법을 읽는 것과 상당히 복잡하다는 것에 조금 실망했다.

Camel은 어플리케이션에 부속되어 있는 것과 같은 Jackson bean을 사용하여 Spring 디폴트오브젝트 맵퍼를 쉽게 사용할 수 있도록 해야 한다고 생각합니다.

의 사용을 용서했다..json()프로세서로 교환했습니다.

다음과 같이 스프링에서 제공한 objectMapper를 사용했습니다.

경로

from(CONSUME_TAG)
 .process("jsonProcessor")
 .to("direct:anotherRoute")
 .end();

범용 프로세서는 이것이 스프링 부트 오브젝트 맵퍼빈을 자동화하는 방법을 통지합니다.

@Component
public class JsonProcessor implements Processor {

    @Autowired
    ObjectMapper objectMapper;

    @Override
    public void process(Exchange exchange) throws Exception {
        exchange.getOut().setBody(objectMapper.writeValueAsString(exchange.getIn().getBody()));
    }

}

스프링 부트 구성ObjectMapper필요에 따라서jackson-datatype-jsr310spring context에 저장합니다.

새 버전의 Camel은 사용하지 않습니다.ObjectMapper기본적으로 Spring Context를 형성하고 자체 생성ObjectMapper없이.jackson-datatype-jsr310.

  1. 이후 Camel의 새로운 버전3.15.0이것을 에 추가하다application.yaml
camel.dataformat.jackson.auto-discover-object-mapper: true
  1. 마샬을 해제하는 데 사용
from("some").unmarshal().json(SomeClass.class)

그리고 사용하지 마세요.

from("some").unmarshal(new JacksonDataFormat(SomeClass.class))

얻을 수 없다ObjectMapperSpring Context에서 확인하세요.

디버깅을 확인하려면AbstractJacksonDataFormat.doStart()방법.Camel 스타트업 중에 불러서ObjectMapperSpring Context에서 작성하거나 새 Spring Context를 만듭니다.새로운 경우ObjectMapper잭슨을 필요로 하지 않습니다.jackson-datatype-jsr310에러가 발생합니다.

언급URL : https://stackoverflow.com/questions/33397359/how-to-configure-jackson-objectmapper-for-camel-in-spring-boot

반응형