使用 JAXB 和 JAXWS 注释将枚举属性编组到 XML 中

发布于 2024-12-12 23:52:50 字数 2047 浏览 0 评论 0原文

假设我们有以下 Java 1.5 枚举:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.FIELD)
public enum ReturnCode {
    OK(0,"Ok"),
    ERROR_VALIDATION(1,"Validation Error"),
    ERROR_TRANSPORT(2, "Transport Error"),
    ERROR_CASE_01(101, "Business situation #01"),
    ERROR_CASE_02(102, "Business situation #02"),
    ERROR_CASE_03(103, "Business situation #03");

    @XmlElement(nillable=false, required=true)
    private Integer code = 0;

    @XmlElement(nillable=false, required=true)
    private String message = null;

    private ReturnCode(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

我正在使用 Apache CXF,并且生成的 WSDL 正如预期的那样,将上述枚举转换为限制:

<xsd:simpleType name="ReturnCode">
    <xsd:restriction base="xsd:string">
        <xsd:enumeration value="OK"/>
        <xsd:enumeration value="ERROR_VALIDATION"/>
        <xsd:enumeration value="ERROR_TRANSPORT"/>
        <xsd:enumeration value="ERROR_CASE_01"/>
        <xsd:enumeration value="ERROR_CASE_02"/>
        <xsd:enumeration value="ERROR_CASE_03"/>
    </xsd:restriction>
</xsd:simpleType>

到目前为止一切顺利,这是一个理想的功能。我自己记得在 Apache CXF 之前(当我使用 XFire 时)就曾与此类结构作过斗争。

然而,这里的情况并非如此。我想产生不同的结果。我希望在编组包含此枚举实例的对象时,将枚举转换为复杂类型,并将属性代码和消息转换为 XML 元素。我只希望它的行为不像枚举。我知道如果我使用普通类而不是枚举,我可以实现这一点。但是,我非常希望将其保留为枚举,因此我在代码的 java 部分中将其保持为类型安全。

如果生成的 WSDL 仍然对可能的值有限制,那么这将是完美的场景。不过,我可以没有它。这里的主要内容是使其保持 Java 1.5 枚举,同时仍将 ReturnCode 编组(并生成 WSDL)作为复杂类型,并以代码和消息作为其元素。

我试图暗示,将给定的 JAXWS 注释放置在枚举源代码中。仅使用这些(或其他一些)注释是否可以以某种方式实现这一点?或者我是否必须编写自定义编组器/解组器和 WSDL 生成器?

非常感谢!

最好的问候,

菲利普·费达尔托

Let's say we have the following Java 1.5 enumeration:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.FIELD)
public enum ReturnCode {
    OK(0,"Ok"),
    ERROR_VALIDATION(1,"Validation Error"),
    ERROR_TRANSPORT(2, "Transport Error"),
    ERROR_CASE_01(101, "Business situation #01"),
    ERROR_CASE_02(102, "Business situation #02"),
    ERROR_CASE_03(103, "Business situation #03");

    @XmlElement(nillable=false, required=true)
    private Integer code = 0;

    @XmlElement(nillable=false, required=true)
    private String message = null;

    private ReturnCode(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}

I am using Apache CXF and the generated WSDL, as expected, translates the aforementioned enum into a restriction:

<xsd:simpleType name="ReturnCode">
    <xsd:restriction base="xsd:string">
        <xsd:enumeration value="OK"/>
        <xsd:enumeration value="ERROR_VALIDATION"/>
        <xsd:enumeration value="ERROR_TRANSPORT"/>
        <xsd:enumeration value="ERROR_CASE_01"/>
        <xsd:enumeration value="ERROR_CASE_02"/>
        <xsd:enumeration value="ERROR_CASE_03"/>
    </xsd:restriction>
</xsd:simpleType>

So far so good and it is a desirable feature. I myself remember to be struggling with such structures before Apache CXF (back when I used XFire).

However, this is not the case here. I want to produce a different result. I want that the enum be translated into a Complex Type and that both attributes code and message are translated into XML elements when an object containing an instance of this enumeration is marshalled. I only want it to not behave like an enum. I know I could accomplish that if I used a plain class instead of an enum. However, I'd very much like to keep it an enum so I kept it type-safe in the java-part of the code.

If the generated WSDL could still have a restriction as to the possible values, it would be the perfect scenario. I could do without it, however. The main thing here would be to keep it a Java 1.5 enum while still marshalling (and generating a WSDL) ReturnCode as a Complex Type with code and message as its elements.

I tried to hint that with the given JAXWS Annotations placed in the enum source code. Is it somehow possible to accomplish that with just those (or some other) annotations? Or would I have to write a custom marshaller/unmarshaller and WSDL-generator?

Thank you very much!

Best regards,

Filipe Fedalto

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

动次打次papapa 2024-12-19 23:52:51

在 Java 服务器代码中使用枚举并在服务接口中转换为复杂类型。

例子:

@WebMethod
public ComplexType GetInfo(){
  ReturnCode response;
  response = ReturnCode.OK;
  ComplexType wsResponse;
  wsResponse = response.toComplexType()
  return wsResponse;
}

@WebMethod
public void PutInfo(ComplexType input){
  ReturnCode request = ReturnCode.fromComplexType(input);
  //more code
}

Use enums in your java server code and translate to complex type in the interface of you service.

Example:

@WebMethod
public ComplexType GetInfo(){
  ReturnCode response;
  response = ReturnCode.OK;
  ComplexType wsResponse;
  wsResponse = response.toComplexType()
  return wsResponse;
}

@WebMethod
public void PutInfo(ComplexType input){
  ReturnCode request = ReturnCode.fromComplexType(input);
  //more code
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文