问题 如何在Spring Boot中为Camel配置Jackson ObjectMapper
我正在尝试使用Jackson在Camel路由上对JSON进行序列化和反序列化。其中一些有Java 8 LocalDate字段,我希望它们被序列化为YYYY-MM-DD字符串,而不是整数数组。
我们只对我们的Spring Boot应用程序使用Java配置,因此没有XML Camel配置。
我已成功创建了一个ObjectMapper,它可以实现我想要的功能,我们系统的其他部分正在使用它来添加到我们的依赖项:
<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会创建自己的ObjectMapper实例,因此不会选择JSR310序列化程序/反序列化程序 Jackson2ObjectMapperBuilder
自动添加或禁用 WRITE_DATES_AS_TIMESTAMPS
特征。我看过了 骆驼JSON 文档,但它没有说明如何使用Spring配置添加自定义DataFormat,或者如何为所有类型应用全局自定义。
那么如何使用Spring Boot Java配置告诉Camel使用我的ObjectMapper?
5939
2017-10-28 17:11
起源
答案:
我已经通过单步执行Camel代码找到了解决方案。因此,虽然它可以满足我的需求,但它可能不适用于未来的Camel版本,因为它似乎没有文档记录且可能不受支持。
我所做的就是将以下bean添加到我的Spring配置中,除了我的 ObjectMapper
bean中的问题:
@Bean(name = "json-jackson")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public JacksonDataFormat jacksonDataFormat(ObjectMapper objectMapper) {
return new JacksonDataFormat(objectMapper, HashMap.class);
}
需要注意的关键点:
- 没有构造函数
JacksonDataFormat
需要一个 ObjectMapper
没有unmarshal类型。但是,在默认构造函数中 HashMap.class
当没有提供unmarshal类型时使用,所以我使用它。通过一些魔术,这似乎习惯于解组所有POJO类型。如果您还需要其他类的更具体的数据格式,则需要设置 ObjectMapper
在他们中间。
- Camel似乎在bean注册表中搜索一个名为“json-jackson”的bean,因此设置Spring bean使用该名称会欺骗Camel而不是创建一个新的并使用我的。
- bean范围必须设置为
SCOPE_PROTOTYPE
因为REST DSL期望得到一个新的实例 DataFormat
。看到 CAMEL-7880。
5
2017-10-30 09:21
创建 JacksonDataFormat
在java代码中启用/禁用所需的功能,然后在Camel路由中使用该实例。
.unmarshal(myInstanceGoesHere).
3
2017-10-29 07:17
使用Spring和Camel 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>
在一个 CamelContextConfiguration
上课,自动装配 JacksonDataFormat
为了配置类路径模块的发现和序列化选项的配置:
@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);
}
}
2
2017-12-22 13:04
我设法使用非常方便地为Camel配置ObjectMapper org.apache.camel:camel-jackson-starter:2.20.0
它通过Spring应用程序属性公开了一些有用的ObjectMapper属性。例如,可以从application.yaml或application.properties文件直接设置WRITE_DATES_AS_TIMESTAMPS。
查找JacksonDataFormatConfiguration类以获取更多详细信息。
我还需要使用一些Mixins,所以我仍然需要配置Camel来使用Spring的ObjectMapper。我最终得到了这个:
配置bean:
@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
return new Jackson2ObjectMapperBuilderCustomizer() {
@Override
public void customize(Jackson2ObjectMapperBuilder builder) {
builder.mixIn(Person.class, PersonMixin.class);
}
}
}
application.yaml:
camel:
dataformat:
json-jackson:
disable-features: WRITE_DATES_AS_TIMESTAMPS
object-mapper: jacksonObjectMapper
哪里 jacksonObjectMapper
是由配置的Jackson2ObjectMapperBuilder构建的ObjectMapper bean的名称
2
2017-10-18 12:50
到目前为止,只有@ david-edwards的建议对我有用。我首先定义了一个id为“json-jackson”的数据格式bean
<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();
}
}
}
1
2018-04-15 01:30
如果有人想知道如何使用版本中的修复程序。 2.17 ..
我使用这个xml配置工作了:
<camel:camelContext id="defaultCamelContext">
.....
<camel:dataFormats>
<camel:json id="json" library="Jackson" objectMapper="myObjectMapper"/>
</camel:dataFormats>
</camel:camelContext>
..where myObjectMapper是ObjectMapper类型的spring bean的名称
1
2018-03-23 17:30
如果Camel在那里给你带来麻烦,我会直接使用bean:
只需创建一个可以进行编组和解组的小型Json实用程序,并将预配置的ObjectMapper自动装入其中。
Harness Camels非常棒的Spring bean集成来调用你的实用程序并在路由中转换Message,例如:
from(uri)
.unmarshal().json(JsonLibrary.Jackson)
.beanRef("jsonUtil", "unmarshal")
.bean(myBean);
0
2017-10-29 17:11
我无法让任何一个例子起作用。有点失望的是,阅读变通方法非常复杂。
在我看来,camel应该通过使用应用程序附带的相同Jackson bean来轻松使用Spring默认对象映射器。
我放弃了使用 .json()
并将其换成处理器。
如下所示,这使用了Spring提供的objectMapper。
路线
from(CONSUME_TAG)
.process("jsonProcessor")
.to("direct:anotherRoute")
.end();
通用处理器 注意这是如何自动启动spring引导的objectMapper bean。
@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()));
}
}
0
2018-03-23 13:41