Java 如何使用生成器反序列化包含泛型类型的对象?

Java 如何使用生成器反序列化包含泛型类型的对象?,java,jersey,jackson,deserialization,dropwizard,Java,Jersey,Jackson,Deserialization,Dropwizard,我目前正在用dropwizard开发一个小型web应用程序。另一个应用程序可以向我的应用程序发送多种类型的消息。根据消息的类型,这些消息具有共同的基础和特定的内容 以下是消息的共同基础: @JsonDeserialize(builder = BaseMessageBuilder.class) public abstract class BaseMessage<T> { private String commonFiled; private T content;

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

以下是消息的共同基础:

@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;
    }
}
@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);
    }
}

已尝试此操作,但当前不支持此操作似乎:

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

我有一条基本信息:

public class BaseMessage<T> {

    @JsonProperty("val1")
    String val1;
    @JsonProperty("val2")
    T val2;
}
利用这一资源:

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

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

}
@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();
    }
}
@Path(“/builder”)
@产生(MediaType.APPLICATION_JSON)
公共类BuilderResource{
@职位
@路径(“/test”)
@使用(MediaType.APPLICATION_JSON)
@产生(MediaType.APPLICATION_JSON)
公共响应测试(BaseMessage testContent){
System.out.println(“命中正常内容”);
返回Response.ok().build();
}
@职位
@路径(“/test2”)
@使用(MediaType.APPLICATION_JSON)
@产生(MediaType.APPLICATION_JSON)
公共响应test2(BaseMessage testContent){
System.out.println(“命中字符串内容”);
返回Response.ok().build();
}
}
点击测试URL,jackson成功地检测到基本内容的类型T并创建正确的实例

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

我希望这有帮助


Artur

感谢@pandaadb的回复。恐怕我得想个办法。我想保留我的生成器,以便拥有不可变的对象。我将尝试创建我自己的反序列化程序。@ThomasBetous你有没有研究过创建者?它们工作得很好,看起来非常相似。那可能是你的解决办法是的,对我有帮助。谢谢您可以在“编辑”中找到我的解决方案。
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();
    }
}