2013-06-05 61 views
0

我们在使用Jersey时遇到了通用Payload的问题。这是我们的Domain对象。Jersey Jaxb问题

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Event<T> { 
    private T eventPayload; 
    private String eventType; 
} 

这里我们定义了顶级域对象。但内部域对象是通用的。

现在在资源端点上我们有类似的东西,因为我们知道我们期望的子域对象是。

@POST 
    @Path("log") 
    @Consumes(MediaType.APPLICATION_XML) 
    public Response writeLog(Event<LogPayload> event) 

但这不起作用。 事件实例已创建,但子域未正确填充。 它只是试图用任何随机域对象填充子域对象,该对象具有与XML中相同的根元素(可能有多个)。

我们的解决方案: 这是我们的解决方案,但我相信这不是最好的。

我们必须修改我们的父域对象有一个字符串变量,它以字符串格式存储通用有效负载的XML表示。为此,我们不得不编写我们自己的Jaxb编组人员。 修改到事件

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Event<T> { 
    @XmlTransient 
    private T eventPayload; 
    private String eventType; 
    private String payLoadXML; 

// Changes to the constructor: 
public Event(T eventPayload ……) { 
      super(); 
      this.eventPayload = eventPayload; 
      payLoadXML = JAXBUtils.marshall(eventPayload,false); }} 

在资源方面,一旦我们得到父事件对象,我们必须再次使用我们自己的JAXB编组从payloadXML获得所需的域对象,如下所示。

@POST 
    @Path("log") 
    @Consumes(MediaType.APPLICATION_XML) 
    public Response writeLog(Event<LogPayload> event) 
      LogPayload log1 = (LogPayload) JAXBUtils.unMarshall(
            event.getPayLoadXML(),LogPayload.class); 

所以ineffect我们运用jaxbmarshaller马歇尔之前,使其余的电话......之后解组通用的子域对象。

请让我们知道是否有更好的方法来做到这一点?

感谢, ND

回答

0

我以前见过同样的问题,我不认为这会工作,你原本打算。 Web服务(json/xml,rest/soap)通常会创建服务描述(如wsdl),而技术上通用类型不能成为此描述的一部分。你可以做的是发布多个服务,其中Event不再是通用的。

+0

感谢您的回复。好。我不认为这是一个选项。有效载荷可以是任何物体的绝对。我们稍后可能会添加新的域对象。我们不可能有多种服务,以便Event不再是通用的。那么我们的解决方案将起作用,因为我们使用JAXB将subobejct作为String-XMLabd发送,以将它解组回到所需的对象。唯一的问题是它看起来很乱,可能是资源密集型的。 – user2008203

+0

你也可以使用一个超类(例如有效载荷),它有一个属性映射并且可以序列化。你可以用这张地图包裹每个有效载荷。当然这种方法有一些限制,它不是真正的面向对象的方式,但它应该起作用。我稍后会设置一个测试项目,因为我也想找到一个体面的解决方案:) –

+0

嗯..可能工作..但正如你所说的不是太面向对象。我们的方法再次具有相同的优点和缺点。我正在寻找更清洁的解决方案。很高兴知道你是否找到一个。 :) – user2008203