【问题标题】:Jackson don't deserialize properties value杰克逊不反序列化属性值
【发布时间】:2020-07-23 12:58:52
【问题描述】:

我有这样的继承和泛型的 pojo 对象:

子对象:

@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class MessageCreatedEvent extends AbstractEvent<MessageDto> {

    @JsonCreator
    public MessageCreatedEvent(MessageDto data) {
        super(data);
    }
}

父母:

@Data
public abstract class AbstractEvent<T> {

    private final UUID id = UUID.randomUUID();
    private T data;

    public AbstractEvent(T data) {
        this.data = data;
    }
}

和内容持有对象:

@Data
public class MessageDto implements Serializable {

    private UUID id;

    private String content;

    // and other fields
}

和rabbitTemplate中使用的jackson配置:

@Bean
public MessageConverter jsonMessageConverter() {
    return new Jackson2JsonMessageConverter();
}

一开始我没有使用@JsonCreator 属性,但是当我收到来自 RabbitMQ 的 json 消息并尝试在兔子处理程序中反序列化时,我收到了这个错误:

原因:com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造MessageCreatedEvent 的实例(不存在像默认构造函数一样的创建者):无法从对象值反序列化(没有基于委托或属性的创建者)

在此之后,我添加了@JsonCreator,但未设置 MessageDto 对象中的属性。只有id字段填写,其他为空。

你能告诉我我的配置有什么问题吗?谢谢。

编辑:

我尝试修改 pojos 并从父级删除通用数据字段,并将其移至子级,现在反序列化工作,所以看起来杰克逊在泛型方面存在一些问题。有什么想法吗?

【问题讨论】:

  • 我猜你已经将 Jackson 配置为仅使用属性 getter/setter。如果您想将其配置为直接操作类成员变量(又名字段):stackoverflow.com/questions/7105745/…
  • @TrogDor 我找到了如何将它设置到我正在使用但没有帮助的 Jackson2JsonMessageConverter 中
  • @denis-stephanov,您尝试以下选项了吗?
  • @denis-stephanov “我尝试修改 pojos 并从父级删除通用数据字段,并将其移至子级”是什么意思?你能进一步解释一下以帮助理解问题吗?
  • @JoséCarlosCampanero 所以我从父级中删除了泛型,并将所需类型的 data 字段添加到子级

标签: java spring-boot jackson spring-amqp spring-rabbit


【解决方案1】:
  • 我在示例 Spring Boot 应用程序中复制了您的类(我没有使用 Lombok,而是复制了它的行为)并执行以下操作并且正在工作
    public class Testing {

      public static void main(String[] args) throws 
                  JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        MessageDto data = new MessageDto(UUID.randomUUID(), 
                                         "someContent");
        MessageCreatedEvent createdEvent = new MessageCreatedEvent();
        createdEvent.setData(data);
        String json = objectMapper.writeValueAsString(createdEvent);
        System.out.println(json);
        MessageCreatedEvent fromJson = 
            objectMapper.readValue(json, MessageCreatedEvent.class);
        System.out.println(fromJson.getData().getContent());
        System.out.println(fromJson.getData().getId());
      }
    }
  • MessageDto添加了一个无参数构造函数

  • AbstractEvent添加了一个无参数构造函数

  • 删除了以下内容并且是空类:

      @JsonCreator
      public MessageCreatedEvent(MessageDto data) {
          super(data);
      }
    

【讨论】:

    【解决方案2】:

    我不确定它是否有帮助,但您可能需要使用 @JsonProperty。具体可以参考https://thepracticaldeveloper.com/2016/10/23/produce-and-consume-json-messages-with-spring-boot-amqp/

    【讨论】:

    • 我在我的项目中使用相同的配置,只有区别 - 使用消息的通用 pojo。当我删除通用消息时,开始正常工作。
    • 哦,很高兴听到这个消息。
    • 这不是很大的成功,因为我只发现了真正的问题,现在我必须找到解决方案:)
    猜你喜欢
    • 2017-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    • 2016-08-24
    • 1970-01-01
    • 2016-01-27
    • 2017-12-19
    相关资源
    最近更新 更多