【问题标题】:How to use polymorphism and generic class hierarchies with JAXB如何在 JAXB 中使用多态性和泛型类层次结构
【发布时间】:2017-03-17 00:13:13
【问题描述】:

我使用 Jersey 和 JAXB 来为 web 服务调用输出 JSON,我有一个来自域模型类的通用类型类层次结构,我需要输出特定类的结果:

@XmlRootElement 
public class OfferDto extends BaseEntity<String> {
  private String name;
  private String description;

// ...
}
public class OfferListResponse extends BaseListResponseImpl<OfferDto> { 
}



public abstract class BaseListResponseImpl<T> implements BaseListResponse<T> {

    private List<T> data;
    public List<T> getData() {
        return data;
    }
    public void setData(List<T> data) {
        this.data = data;
    }       
}



public interface BaseListResponse<T> extends Serializable {
    public List<T> getData();
}

在我的网络服务上,我返回:

OfferListResponse resp = offerService.getOfferList(params);
Response.status(Response.Status.OK).entity(resp).build();

但我的 JSON 输出为:

{"data":["sample.dto.OfferDto@2165c59c","com.sample.dto.OfferDto@fa69c419", ..."}]}

似乎 JAXB 正在调用 toString 方法而不是正确输出对象字段。

如果我直接在类中使用具体类型而不进行任何继承:

@XmlRootElement
public class OfferListResponse {
    private List<OfferDto> data;
// ... getters and setters
}

现在它工作正常。

我试图了解我需要做什么才能将多态性和泛型类层次结构与 JAXB 一起使用?

【问题讨论】:

    标签: java json generics jaxb unmarshalling


    【解决方案1】:

    使用ObjectMapper

    例如new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString() 将对象漂亮地映射到 String

    我创建了一个接口 JSONMappable,它允许我将对象编写为响应或对象

    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.Response;
    
    public interface JSONMappable {
    
      ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    
      default Response asOKJsonResponse() {
        try {
          String json = OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(this);
          return Response
            .ok(json, MediaType.APPLICATION_JSON + "; charset=UTF-8")
            .build();
        } catch (JsonProcessingException e) {
          return Response.serverError().build();
        }
      }
    
      default Object asJSON() {
        try {
          return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(this);
        } catch (JsonProcessingException e) {
          return Response.serverError().build();
        }
      }
    }
    

    然后我在所有需要序列化为 JSON 的资源中实现这个接口。

    所以在你的网络服务中你会使用

    return offerService.getOfferList(params).asJSONOKResponse;
    

    接口的使用最大限度地减少了 web 服务中的混乱

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-18
      • 2016-09-14
      • 2013-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多