Java 如何使用生成器反序列化包含泛型类型的对象?
我目前正在用dropwizard开发一个小型web应用程序。另一个应用程序可以向我的应用程序发送多种类型的消息。根据消息的类型,这些消息具有共同的基础和特定的内容 以下是消息的共同基础: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;
@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();
}
}