[RESOLVIDO] Integração de um Web Service a uma aplicação Web já existente com Frameworks

5 respostas
J

Oi pessoal.

Seguinte, tenho uma aplicação web já rodando. Nela eu usei os frameworks: Spring, Spring Security, Hibernate, JSF. O cenário é típico: o Spring gerencia a SessionFactory usada pelo Hibernate através de um bean da classe AnnotationSessionFactoryBean, o qual conecta-se a um datasource JNDI criado no servidor de aplicação (Glassfish).

O controle de sessões é feito por meio do padrão OpenSessionInView, também controlado pelo Spring através do filtro da classe org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.

Tudo funciona perfeitamente, tenho meus objetos DAO’s auto injetados em meus objetos de serviços, que por sua fez são auto injetados nos Managed Beans.

O meu problema agora é que preciso criar um Web Service para comunicação com a mesma base de dados desse sistema e que vai fazer uso das mesmas classes de serviço.

Particularmente é a primeira vez que estou criando web services em java, já conheço por alto a teoria, sei buscar os artefatos, criar o cliente, conheço do WSDL, SOAP 1.2, etc.

Preciso de uma ajuda para integrados meus Web Services ao meu ambiente já existente e de preferência usando os mesmos beans de serviço, pois as operações que serão consumidas pelos clientes são as que as classes de serviços oferecem.

Desde já agradeço a ajuda.

5 Respostas

V

Colega, eu passei pela mesma situação que voce.

Temos uma aplicação WEB e tem uma parte que se comunica com celulares android. para fazer o webservice nós tivemos que criar 4 projetos…

eu criei a parte WEB ; o cara do mobile criou a app android e em paralelo nós criamos uma API onde nessa API temos as DAOs, os Beans e os Facades…
criamos tambem um projeto separado que é o projeto webservice, onde a aplicação WEB e a aplicação do webservice importam a API que criamos…

dai na API tem os métodos específicos que só a parte WEB acessa e tem uns métodos específicos onde só o webservice acessa … e a WEB e o WS conseguem usar as mesmas DAOS, Beans e Facades…

agora eu te chamo atenção para o seguinte: quando nós fizemos esse sistema eu pensei em usar o OpenSessionInView, so que tinha a parte do mobile e eu nao tinha certeza se o filtro ia funcionar nas conexoes vindas dos celulares, entao eu decidi nao arriscar no OpenSessionInView e controlar as conexoes de outra maneira…

se as DAOS e Beans estao dentro do seu projeto WEB, analise o trabalho que voce teria (e se valeria a pena) em retirar essas classes da WEB e jogar em uma API de voces…

nao sei se ficou claro a minha explicação mas espero ter ajudado em algo… a solução para seu problema (creio eu) seja puramente arquitetural…
abraços

J

Oi Victor Neves. Muito obrigado pela ajuda.

Eu entendi bem o que você explicou e realmente parece ser uma solução interessante.

Eu estava justamente pensando em como integrar os meus beans gerenciados pelo Spring nas operações do Web Service.

Mas realmente parece que vou ter mais trabalho se tentar fazer assim.

No meu projeto não está difícil seperar os beans de persistência, DAO’s e de serviços em uma API, o projeto está bem dividido em pacotes especíificos e o acoplamento entre as classes está muito baixo.

Agora todos os exemplos que eu vejo de Web Services usam JPA, não especificamente o Hibernate.

Usam um EntityManager auto-injetado com uma unidade de persistência.

Supondo que eu colocasse meus beans de persistência, DAO’s e de serviços em uma API separada, como eu poderia usar o Hibernate, digo principalmente no controle de transações, abertura e fechamento de sessões? Atualmente isso tudo é feito pelo Spring, através, por exemplo, de anotações @Transactional.

Em meus DAO’s, atualmente, eu tenho um SessionFactory do Hibernate auto-intejetado e uso o método getCurrentSession() de SessionFactory para realizar as operações com o banco de dados.

Como eu poderia continuar usando esse cenário?

Mais uma vez, agradeço a ajuda.

L

Como vc já tem o Spring, pode usar o CXF que se integra facilmente ao Spring, podendo utilizar a estrutura atual do projeto, como a injeção de dependências.

Abaixo tem um arquivo de configuração de um WS usando Spring/CXF.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:jaxws="http://cxf.apache.org/jaxws"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

        <import resource="classpath:META-INF/cxf/cxf.xml" />
        <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

        <bean id="UsuarioServiceWSImpl" class="br.net.woodstock.caa.api.ws.impl.UsuarioServiceWSImpl" autowire="byType" />

        <jaxws:endpoint id="UsuarioServiceWS" implementor="#UsuarioServiceWSImpl" address="/UsuarioServiceWS">
                <jaxws:inInterceptors>
                        <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
                </jaxws:inInterceptors>
        </jaxws:endpoint>

</beans>

Nas versões mais recentes do Spring acho que nem precisa mais importar o resource. Nesse caso de exemplo as classes usam as anotações padrões JEE 5 para WS.

V

bom, eu nao conheço essa anotação @Transactional

mas eu to fazendo assim…

na Action (é que eu to usando struts1 rsrs) eu tenho um método que instancia um facade, dai no construtor do facade eu instancio uma DAO, e no construtor da DAO eu peço uma conexao par ao hibernate e armazeno numa variavel de classe onde todos o metodos usam essa variavel de classe pra conexao… dai antes de sair da action, ela chama um metodo no facade que encapsula um metodo da DAO que fecha a conexao, pra voce entender melhor, olha ai o exemplo.

public class QualquerAction{ public execute(){ FacadeQualquer facade = new FacadeQualquer(); // faz um monte de trabalhos aqui e no final de tudo... facade.fecharConexao(); // fecha a conexao } }

public class FacadeQualquer{ QualquerDao dao; public FacadeQualquer(){ dao = new QualquerDao(); } //varios metodos encpsulando as DAOs public void fecharConexao(){ dao.fecharConexao(); } }

public class QualquerDao{ SessionFactory sessao; public QualquerDao(){ sessao = HIbernateUtil.getSessao(); } // varios metodos usando a sessao ja instanciada public void fecharConexao(){ sessao.close(); } }

e é assim que eu controlo as conexoes, foi esse o meio alternativo aque achei em troca do OpenSessionInView … é UMA sessao a CADA facade, consequentemente é UMA conexao para varios metodos da DAO que sao usadas na mesma requisição… entendeu o que eu fiz, no codigo?

J

Galera, agradeço pela ajuda.

Eu resolvi o problema usando o Apache CXF. Como já tinha o Spring integrado usar o CXF foi tranquilo.

Agora vou começar a criar as operações do WS e iniciar o desenvolvimento do app para Android.

Valeu!

Criado 2 de julho de 2012
Ultima resposta 3 de jul. de 2012
Respostas 5
Participantes 3