2011-11-18 157 views
0

我有一个Jeresey应用程序。我有几个资源使用注释了javax.xml注释的bean来注册提供程序,因此结果将返回xml或json,具体取决于接受头中发送的内容,其中xml是默认值。所有的工作正常。现在,我需要为每个响应添加一个根元素。有没有办法让javax.xml有一个根元素包装?

这里是一个示例提供者Bean,资源用数据设置并返回结果。

import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement(name = "error") 
public class ErrorProvider { 


private String errorCode; 
private String errorMessage; 

public ErrorProvider(){} 

public ErrorProvider(final String errorCode,final String errorMessage){ 
    setErrorCode(errorCode); 
    setErrorMessage(errorMessage); 
} 

@XmlAttribute(name = "number") 
public String getErrorCode() { 
    return errorCode; 
} 

public void setErrorCode(final String errorCode) { 
    this.errorCode = errorCode; 
} 

@XmlElement 
public String getErrorMessage() { 
    return errorMessage; 
} 

public void setErrorMessage(final String errorMessage) { 
    this.errorMessage = errorMessage; 
} 
} 

上的资源的方法的产生注解是:

@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}) 

所以默认返回是在XML除非JSON是在该请求的接受头中定义。就像我说的,这工作正常。它返回像这样:

<error code="100"> 
    <errorMessage>An error occurred</errorMessage> 
</error> 

好吧,足够的背景下,现在的问题。我需要为所有这些提供者添加一个根元素,这对所有提供者都是一样的。所以它看起来是这样的:

<transaction> 
    <status>ok</status> 
    <error code="100"> 
     <errorMessage>An error occurred</errorMessage> 
    </error> 
</transaction> 

在类级别有类似@XmlElementWrapper会很酷。我试着创建另一个用javax.xml注释的bean,并试图扩展它,试图做一个泛型类型的bean。我无法弄清楚。我能够做的最好的事情是在错误XML中使用事务注释,就像它是另一个元素一样。我知道我可以编辑每个提供者bean来包含事务根元素,但我认为应该有一种方法来创建一次并应用于每个提供者bean。

+0

你能不能创建一个bean叫'Transaction'有场'状态'和'ErrorProvider'类型的另一个字段'error',并相应地添加注释? –

+0

以[深入研究jaxb的工作方式](http://blog.xebia.com/2011/03/17/jaxb-xml-data-binding),我想你正在寻找'@ XmlType',但我' m不知道你的问题 –

+0

T Man - 我想到了这一点,它对于这种情况非常有效,但我有多个提供者bean,我需要这样做,所以它不是一个可行的解决方案,有多个提供者在主事务bean中输入字段。 – Elrond

回答

0

您可以添加一个ContainerResponseFilter,它使用Transaction对象来包装您的响应。这是怎么可能看起来像(未经测试):

public class MyFilter implements ContainerResponseFilter { 
    @Override 
    public ContainerResponse filter(ContainerRequest request, ContainerResponse response) { 
     response.setEntity(new Transaction(response.getEntity())); 
     return response; 
    } 
} 

您可以了解更多关于如何在此注册过滤器:http://jersey.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/api/container/filter/package-summary.html

+0

这听起来很有希望。这听起来像来自资源方法的响应将被过滤到那里我可以应用标准包装元素。我会给它一个镜头。 – Elrond

+0

没错 - 您将拥有一个事务Bean(用XmlRootElement注释),当过滤器被调用时,它将修改响应,使其通过Transaction对象包装当前实体。所以,一旦泽西试图组队,它应该吐出正确的东西。确保你的Transaction类具有公共的默认构造函数,以及一个接受你想要包装的类型的类(上面的代码在传递给Transaction构造函数时应该转换为该类型)。 –

+0

这实际上效果很好,我认为这是更好的方式,在出路上。我想过滤器用于每个响应,但实体可能是任何提供程序bean的实例。这是我能够做到的唯一方法。为实体可能的每个提供者bean定义事务bean的属性。在过滤器上检查实体的实例并适当地进行投射。有没有办法来证明整个过程?我不知道如何设置事务bean来了解它可能需要处理的不同类型。 – Elrond

相关问题