11 janeiro 2011

JAX-WS, Spring, Maven e Tomcat 7

Mais um post técnico, pra variar (será que um dia eu fico só sentado numa cadeira, mandando as pessoas fazerem coisas?). Essa foi a minha dificuldade nesses dias, tentar fazer o deploy de um web service utilizando JAX-WS, o Spring e o Maven.

Bem, ao contrário de todos os post's que eu pesquisei na internet, eu não precisei fazer uso do plugin jaxws-maven-plugin para gerar os wsdl's. Este plugin dá acesso aos comandos wsgen e wsimport a partir do maven, e utilizando o wsgen é possível gerar os tais arquivos wsdl. Também não vou considerar como importar os tipos descritos em arquivos do tipo xsd, visto que deve-se usar o comando xjc do JDK para isso.

Considerando que as dependências do spring já foram devidamente colocadas no arquivo pom.xml, adicionei estas outras dependências, para o jax-ws:

...
    <!-- JAX-WS -->
    <dependency>
        <groupId>com.sun.xml.ws</groupId>
        <artifactId>jaxws-tools</artifactId>
        <version>${jaxws.version}</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.ws</groupId>
        <artifactId>jaxws-rt</artifactId>
        <version>${jaxws.version}</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>${jaxws.version}</version>
    </dependency>
    ...
    <properties>
        ...
        <jaxws.version>2.2.1</jaxws.version>
        ...
    </properties>

Feito isso, criei um arquivo chamado sun-jaxws.xml, com o seguinte conteudo:

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
    <endpoint    name="MeuWebService" 
                    implementation="com.blogspot.sfohart.ws.jaxws.MeuWebServiceImpl"
                    url-pattern="/MeuWebService" />
</endpoints>

Após isso, alterei o meu arquivo web.xml, adicionando as linhas abaixo:
...
<!-- Para o suporte a Web Services -->
<listener>
    <listener-class>
        com.sun.xml.ws.transport.http.servlet.WSServletContextListener
    </listener-class>
</listener>
...
<!-- Para acesso ao Meu Web Service -->
<servlet>
    <description>Meu Web Service JAX-WS</description>
    <display-name>MeuWebService</display-name>
    <servlet-name>MeuWebService</servlet-name>
    <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>MeuWebService</servlet-name>
    <url-pattern>/MeuWebService</url-pattern>
</servlet-mapping>
...

Quando eu acessei meu web service através do mapeamento definido no web.xml, encontrei a seguinte tela:

Clique aqui para ver a imagem em tamanho maior

Clicando no link mostrado, nos é dado o código wsdl para o nosso web service, o mesmo que seria gerado se utilizássemos o wsgen. Caso você tenha importado classes java através do comando xjc, note que seu código wsdl gerado fará referência a arquivos xsd através das tags xsd:import.

Agora fica a pergunta: onde está o suporte ao Spring? Pois bem. Em muitos blogs, vi tutoriais mostrando como configurar os arquivos de contexto. Entretanto, eu não precisei fazer nada disso, visto que fiz uso da classe SpringBeanAutowiringSupport do Spring. Esta classe faz a amarração das propriedades que nós anotamos no web service com o contexto do spring da maneira mais transparente possível.

@WebService(serviceName="MeuWebService")
@SOAPBinding(parameterStyle=ParameterStyle.BARE)  
public class MeuWebServiceImpl extends SpringBeanAutowiringSupport {

    ...

    @AutoWire
    private ComponenteQualquer componenteQualquer;

    ...

}

Para testar seu web service, pegue aquele link que gera o código wsdl e utilize o comando wsimport do java para criar as classes do cliente deste webservice. Vasculhando o código gerado, é fácil verificar quais arquivos serão utilizados para o acesso ao web service no servidor, mas se por acaso surgirem dúvidas, tente criar o cliente como mostrado neste link. Teste o Auto Wiring do Spring colocando breakpoints nos componentes e verificando se a execução para por lá.

Agora eu preciso descobrir como embutir uma assinatura digital nessa troca de mensagens, se por acaso alguém souber como... 

UPDATE: Tive mais alguns problemas ao tentar utilizar esse ambiente com o JSF 2.0, e o meu erro foi simples: tentar utilizar os Servlets 3.0 do Tomcat 7. Aconteciam diversos conflitos em relação ao jaxb-xjc que eu não conseguia resolver, até me atentar a este fato. Portanto, utilizem, no máximo, a versão 2.5 da servlet-api.

Veja também:
WSDL - Web Services Description Language
Web Services



Creative Commons License
Esta obra está licenciada sob uma Licença Creative Commons.
Comentários
2 Comentários

2 comments:

Luciano disse...

Parabéns pelo post, muito útil.
Estou tentando fazer funcionar uma estrutura muito semelhante, porém utilizando o CXF, para rodar no Weblogic e apanhando muito com incompatibilidade de classes.

Ivaldo Oliveira disse...

É necessário incluir o repositório onde encontrar as dependencias.

<repository>
<id>maven2-repository.java.net</id>
<name>Java.net Repository for Maven</name>
<url>http://download.java.net/maven/2/</url>
<layout>default</layout>
</repository>

Postar um comentário

Regras são chatas, mas...

- Seu comentário precisa ter relação com o assunto do post;
- Em hipótese alguma faça propaganda de outros blogs ou sites;
- Não inclua links desnecessários no conteúdo do seu comentário;
- Se quiser deixar sua URL, comente usando a opção OpenID;
- CAIXA ALTA, miguxês ou erros de ortografia não serão tolerados;
- Ofensas pessoais, ameaças e xingamentos não são permitidos;