问题描述
我正在尝试使用自定义解串器:
@JsonComponent
class SuffixDeserializer extends JsonDeserializer<String> {
private final String suffix;
SuffixDeserializer(@Value("${suffix}") String suffix) {
this.suffix = suffix;
}
@Override
public String deserialize(JsonParser json,DeserializationContext ctx)
throws IOException {
return json.getText() + suffix;
}
}
对于 RabbitMQ 侦听器:
@Slf4j
@Service
class FooListener {
@RabbitListener(queuesToDeclare = @Queue(name = "foo",durable = "true"))
void foo(Message msg) {
log.info("Received {}",msg);
}
@Data
static class Message {
@JsonDeserialize(using = SuffixDeserializer.class)
private String field;
}
}
我什至试图明确注册 JsonComponentModule
:
@Bean
public MessageConverter jsonConverter() {
ObjectMapper mapper = new ObjectMapper()
.registerModule(new JsonComponentModule());
return new Jackson2JsonMessageConverter(mapper);
}
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Class io.github.jjarzynski.jsoncomponentmq.SuffixDeserializer has no default (no arg) constructor
at [Source: (String)"{"field": "bar"}"; line: 1,column: 1]
这意味着 Jackson 正在尝试创建自己的实例,而不是使用 Spring Bean。
如何将自定义 Spring Bean 反序列化器应用于传入 RabbitMQ 消息中的字段?
解决方法
例外情况很明显:
SuffixDeserializer 在 [来源: (String)"{"field": "bar"}";行:1,列:1]
因此您需要在 suffixDeserializer 类上放置一个默认构造函数,并且可能还需要使用 getter 和 setter 来设置后缀。
@JsonComponent
class SuffixDeserializer extends JsonDeserializer<String> {
private String suffix;
SuffixDeserializer() {}
SuffixDeserializer(@Value("suffix") String suffix) {
this.suffix = suffix;
}
@Override
public String deserialize(JsonParser json,DeserializationContext ctx)
throws IOException {
return json.getText() + suffix;
}
}
,
我能够使用 SuffixDeserializer
bean 的唯一方法是通过以下方式注册它:
@Bean
MessageConverter jsonConverter(SuffixDeserializer deserializer) {
SimpleModule jsonComponentModule = new JsonComponentModule()
.addDeserializer(String.class,deserializer);
ObjectMapper mapper = new ObjectMapper()
.registerModule(jsonComponentModule);
return new Jackson2JsonMessageConverter(mapper);
}
这表明 @JsonComponent
扫描对 RabbitMQ 没有用?我不妨用 SuffixDeserializer
注释 @Component
。