如何在JAXB中使用多态和泛型类层次结构

时间:2017-03-17 00:13:13

标签: java json generics jaxb unmarshalling

我使用Jersey和JAXB为webservice调用输出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一起使用?

1 个答案:

答案 0 :(得分:0)

使用ObjectMapper

E.g。 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;

界面的使用可以最大限度地减少网络服务中的混乱