Pergunta
Eu estou usando Axis para modelar um WebService amostra. O que estou fazendo agora é tentar entender quais são as limitações da geração WSDL e código automatizado.
Agora, para alguns código do lado do servidor:
Este é o esqueleto do serviço web de exemplo:
public class TestWebService {
public AbstractAttribute[] testCall( AbstractAttribute someAttribute ) {
....
e minhas classes de dados: public abstract class AbstractAttribute { String nome;
/*get/set for name*/
public abstract T getValue();
public abstract void setValue(T value);
}
public class IntAttribute extends AbstractAttribute<Integer> {
Integer value;
public Integer getValue(){ return value; }
public void setValue(Integer value){ this.value = value; }
}
public class StringAttribute extends AbstractAttribute<String> {
String value;
/* ok, you got the point, get/set for value field */
}
A ferramenta eclipse para Axis2 é muito feliz para gerar um WSDL a partir destas fontes, incluindo o esquema para as classes de atributo, que é:
<xs:complexType name="AbstractAttribute">
<xs:sequence>
<xs:element minOccurs="0" name="name" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="value" nillable="true" type="xs:anyType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="IntAttribute">
<xs:complexContent>
<xs:extension base="xsd:AbstractAttribute">
<xs:sequence>
<xs:element minOccurs="0" name="value" nillable="true" type="xs:int"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="StringAttribute">
<xs:complexContent>
<xs:extension base="xsd:AbstractAttribute">
<xs:sequence>
<xs:element minOccurs="0" name="value" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Agora, se ver algo estranho aqui, AbstractAttribute não tem o ** = abstratas "true" atributo **, e definir um elemento valor anyType, que get reescrita em IntAttribute e StirngAttribute. Eu não sei mesmo se este é um esquema legal (eu não acho que é legal, por sinal).
Mais, se eu tentar gerar um cliente a partir desta wsdl (sempre usando as ferramentas Eclipse) as fontes geradas não irá compilar, porque AbstractAttribute define um
Object localValue;
campo e define Atributo Int / String
int localValue;
e
String localValue;
.. Eu tentei "acomodar" as fontes (sem muitas esperanças, obviamente), e os resultados são de que a tentativa do servidor para criar uma instância AbstractAttribute (jogando um InstantiationException).
Então, minha pergunta é: existe uma maneira de modelo de algo como o modelo de dados acima, ou serviços web e esquemas XML em geral não são as melhores ferramentas para usar para este caso particular
?Solução
Para explicar o problema que você encontrou, ele ajuda a pensar no que Axis precisa fazer quando o seu serviço é chamado.
Axis é simplesmente uma aplicação web java ... quando recebe um pedido de um serviço, ele irá procurar o mapeamento que você definiu para ele. Se ele encontrar um mapeamento, ele tenta criar uma instância das classes necessárias que você definiu para atender à solicitação.
Se você definiu as classes como abstrato ou como interfaces, então você vai ter InstantiationExceptions uma vez que estes tipos não podem ser criados. Quando Axis tentou criar o WSDL, não será capaz de descobrir que tipo de colocar para que ele vai usar "anyType."
Para responder à sua pergunta: você pode usar o modelo você tem acima em seu código, mas você não será capaz de usar essas classes com Axis. O que temos feito tipicamente em nossos projetos é:
- Definir as classes que precisamos, como faríamos em uma aplicação típica Orientada a Objetos
- definem "transport-apenas" classes que são usadas para serviços web. Essas classes são compostas de tipos simples e pode ser facilmente criados. Eles são usados ??somente para a troca de mensagens de serviços web. Nós usamos essas classes com Axis.
- Encontre alguma forma para estes dois tipos de classes para facilmente compartilhar informações / troca. Você pode ter interfaces que são compartilhados por ambos (mas Axis não sabe sobre) ou até mesmo usar BeanUtils.copyProperites para manter dois objetos diferentes em sincronia.
A esperança que responde a sua pergunta.