gpt4 book ai didi

java - 如何使用构建器 Jackson 反序列化包含泛型类型的对象?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:53:35 26 4
gpt4 key购买 nike

我目前正在使用 dropwizard 开发一个小型网络应用程序。另一个应用程序可以向我的应用程序发送多种类型的消息。这些消息具有共同的基础和特定的内容,具体取决于消息的类型。

这是消息的通用基础:

@JsonDeserialize(builder = BaseMessageBuilder.class)
public abstract class BaseMessage<T> {
private String commonFiled;
private T content;

protected BaseMessage(BaseMessageBuilder<T> builder) {
this.commonFiled = builder.getCommonField();
this.content = builder.getContent();
}

public String getCommonField() {
return commonFiled;
}

public T getContent() {
return content;
}
}

这是消息公共(public)基础的构建器:

@JsonPOJOBuilder
public class BaseMessageBuilder<T> {
private String commonFiled;
private T content;

public String getCommonField() {
return commonFiled;
}

public BaseMessageBuilder<T> withCommonField(String commonFiled) {
this.commonFiled = commonFiled;
return this;
}

public String getContent {
return participants;
}

public BaseMessageBuilder<T> withContent(T content) {
this.content = content;
return this;
}

public BaseMessage<T> build() {
return new BaseMessage<T>(this);
}
}

具体内容如下:

@JsonDeserialize(builder = SpecificContentBuilder.class)
public abstract class SpecificContent{
private String field1;
private Long field2;

protected SpecificContent(SpecificMessageBuilder builder) {
this.field1 = builder.getField1();
this.field2 = builder.getField2();
}

public String getField1() {
return field1;
}

public Long getField2() {
return field2;
}
}

下面是具体内容的构建器:

@JsonPOJOBuilder
public class SpecificContentBuilder {
private String field1;
private Long field2;

public String getField1() {
return commonFiled;
}

public SpecificContentBuilder withField1(String field1) {
this.field1 = field1;
return this;
}

public String getField2 {
return field2;
}

public SpecificContentBuilder withField2(Long field2) {
this.field2 = field2;
return this;
}

public BaseMessage build() {
return new BaseMessage<T>(this);
}
}

这是我的资源:

@Path("/test")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class TestResource {

@POST
public void test(BaseMessage<SpecificContent> message) {
// ...
}

}

目前,当我的资源获取对象时,内容消息实际上并未获取正确的类型。当我调试它时,它自动成为一个 LinkedHashMap。我想有什么不对劲。谁能帮帮我?

编辑:

这是一个 Jackson 问题(查看 pandaadb 响应)。我删除了我的 BaseMessageBuilder 并使用了静态构造函数以保持我的对象不可变。

public abstract class BaseMessage<T> {
private String commonFiled;
private T content;

@JsonCreator
public static <T> BaseMessage<T> newInstance(
@JsonProperty("commonFiled") String commonFiled,
@JsonProperty("content") T content) {
return new WebhookEventBuilder()
.withCommonFied(commonFiled)
.withContent(content)
.build();
}

protected BaseMessage(BaseMessageBuilder<T> builder) {
this.commonFiled = builder.getCommonField();
this.content = builder.getContent();
}

public String getCommonField() {
return commonFiled;
}

public T getContent() {
return content;
}

private static class BaseMessageBuilder<T> {
private String commonFiled;
private T content;

public WebhookEventType getCommonFiled() {
return commonFiled;
}

public BaseMessageBuilder withCommonFiled(String commonFiled) {
this.commonFiled = commonFiled;
return this;
}

public T getContent() {
return content;
}

public BaseMessageBuilder withContent(T content) {
this.content = content;
return this;
}

public BaseMessage build() {
return new BaseMessage(this);
}
}
}

最佳答案

试过了,目前似乎不支持:

https://github.com/FasterXML/jackson-databind/issues/921

但是,对于您的示例,这是不必要的。 Jackson 默认做正确的事情,例如,这个代码示例对我有用:

我有 1 个 BaseMessage:

public class BaseMessage<T> {

@JsonProperty("val1")
String val1;
@JsonProperty("val2")
T val2;
}

还有 2 种不同的内容类型:

public class Content {

@JsonProperty("val1")
String val1;
@JsonProperty("val2")
long val2;

}

public class Content2 {

@JsonProperty("val1")
String val1;
@JsonProperty("val2")
String val2;

}

有了这个资源:

@Path("/builder")
@Produces(MediaType.APPLICATION_JSON)
public class BuilderResource {


@POST
@Path("/test")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response test(BaseMessage<Content> testContent) {

System.out.println("hit normal content");
return Response.ok().build();
}


@POST
@Path("/test2")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response test2(BaseMessage<Content2> testContent) {

System.out.println("hit String content");
return Response.ok().build();
}
}

点击测试 url,jackson 成功检测到基本内容的类型 T 并创建正确的实例。

另一种选择是为 BaseMessage 类型编写自己的 MessageBodyReader

希望对你有帮助

阿图尔

关于java - 如何使用构建器 Jackson 反序列化包含泛型类型的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37609284/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com