杰克逊不会反序列化属性值

huangapple go评论84阅读模式
英文:

Jackson don't deserialize properties value

问题

以下是翻译好的内容:

我有带有继承和泛型的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;

    // 和其他字段
}

还有在rabbitTemplate中使用的jackson配置:

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

起初,我没有使用@JsonCreator属性,但是当我从RabbitMQ接收到JSON消息并在rabbit处理程序中尝试对其进行反序列化时,我遇到了这个错误:

由于没有构造函数(如默认构造函数)存在,无法构造MessageCreatedEvent的实例:无法从对象值(无委托或基于属性的创建者)进行反序列化

之后,我添加了@JsonCreator,但是然后在MessageDto对象中的属性没有设置。只有id字段被填充,其他字段为null。

你能告诉我我配置错了什么吗?谢谢。

编辑:

我尝试修改了pojo并从父类中删除了通用数据字段,将其移到了子类中,现在反序列化工作正常,所以看起来Jackson在处理泛型时出现了问题。有什么想法吗?

英文:

I have pojo objects with inheritance and generics like this:

child object:

@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class MessageCreatedEvent extends AbstractEvent&lt;MessageDto&gt; {

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

parent:

@Data
public abstract class AbstractEvent&lt;T&gt; {

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

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

and content holding object:

@Data
public class MessageDto implements Serializable {

	private UUID id;

	private String content;

    // and other fields
}

and jackson configuration which is used in rabbitTemplate:

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

At start I didn't use @JsonCreator property but when I receive json message from RabbitMQ and tried it deserialize in rabbit handler I got this error:

> Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of MessageCreatedEvent (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

After this I added @JsonCreator but then properties in MessageDto object are not set. There is only id field filled and others are null.

Can you tell me what I have wrong configured? Thank you.

EDIT:

I try modified pojos and remove generic data field from parent, and move it into child, now deserialization working, so it looks like that Jackson has som problem with generics. Any idea?

答案1

得分: 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);
}
英文:
  • I copied your classes in a sample spring boot app (I am not using Lombok but replicating its behaviour) and doing the following and is working
    public class Testing {

      public static void main(String[] args) throws 
                  JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        MessageDto data = new MessageDto(UUID.randomUUID(), 
                                         &quot;someContent&quot;);
        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());
      }
    }
  • Added a no argument constructor to MessageDto

  • Added a no argument constructor to AbstractEvent

  • Removed the following and is empty class:

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

答案2

得分: 0

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

英文:

I'm not sure if it can help, but you may need to use @JsonProperty. To be more specific, please refer to https://thepracticaldeveloper.com/2016/10/23/produce-and-consume-json-messages-with-spring-boot-amqp/

huangapple
  • 本文由 发表于 2020年7月23日 20:58:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/63054875.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定