Распределение перечислимых атрибутов в XML с использованием аннотаций JAXB и JAXWS - PullRequest
7 голосов
/ 01 ноября 2011

Допустим, у нас есть следующее перечисление 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, сохраняя маршальный (и генерирующий WSDL) ReturnCode в виде сложного типа с кодом и сообщением в качестве его элементов.

Я попытался намекнуть это с помощью заданных аннотаций JAXWS, помещенных в исходный код перечисления. Можно ли как-то сделать это только с помощью этих (или некоторых других) аннотаций? Или мне нужно написать собственный маршаллер / демаршаллер и WSDL-генератор?

Большое спасибо!

С уважением,

Филипе Федалто

1 Ответ

0 голосов
/ 19 апреля 2012

Используйте перечисления в коде вашего 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
}
...