Webservices + VRaptor

34 respostas
rodrigo.rca31

Pessoal estou começando a mexer com webservice, alguém sabe de um tutorial que explore sobre o assunto e utilize o vraptor como exemplo prático no tomcat ?
Se alguém puder me passar a apostila FJ-31 da caelum também agradeço.

34 Respostas

Lucas_Cavalcanti

o que vc quer dizer por webservices? SOAP+WS-*? REST?

rodrigo.rca31

SOAP + Webservice

H

Lucas aproveitando o topico é possivel criar algo como o WADL para mostrar os serviços de um determinado controller?

Lucas_Cavalcanti

Hermes, não tá implementado isso ainda…

abre uma issue pedindo isso por favor:

H

Você acha então que para esses serviços seria melhor mesclar com o Jersey uma vez que isso já está implementado nele?

Lucas_Cavalcanti

é uma boa idéia. Só tem que ver como fazer isso usando as anotações do VRaptor ao invés das do Jersey.

PS: obrigado pelas issues =)

H

Lucas o Vraptor consegue controlar a criação e destruição de arquivos ?.

Exemplo tenho classe que gera arquivos para um determinado controller para fazer download até ai tudo Bem. Queria saber se o Vraptor consegue controlar esses arquivos,minha preocupação é que esse método que gera arquivos, vai ser chamado por varios pontos da aplicação Web. Será que dentro do método ,colocando dentro de synchronized - Resolveria esse problema ou anotando a classe com @Intercepts.

Ats,

Lucas_Cavalcanti

vc pode anotar métodos com @PostConstruct e @PreDestroy. Esses métodos serão chamados na construção e na destruição do escopo deles (começo e final da request, ou da session ou da aplicação)

H

Obrigado!

H

Lucas eu fiz como vc recomendou anotei a classe com @Componet e o método que gera o arquivo está como @PostContruct e um método destroy() que está anotado com @PreDestroy ,nesse método ele não entra, o @PostContruct e @PreDestroy são do pacote “javax.annotation” está correto ou essas anotations são do Vraptor.

Lucas_Cavalcanti

sim, são as anotações do javax.annotation

vc anotou só com @Component? tem alguma anotação de escopo?

vc está usando Spring, Guice ou Pico?

H

Eu tinha anotado tbm com @RequestScoped - o componente é o mesmo durante uma requisição, mas não vi efeito, e estou usando Spring.

Ats.

Lucas_Cavalcanti

tenta colocar algum log nesses métodos e ver se eles estão sendo chamados… isso deveria funcionar…

o método anotado com o PostConstruct ou PreDestroy deveria retornar void e não receber nenhum parâmetro. Se eu não me engano tem q ser público tb.

H

Sim! Os métodos estão como public void e não recebe nenhum parâmetro, testei agora com a anotation @ApplicationScoped e funcionou coloquei logs para ver se estava passando pelo método e está - @PostConstruct-Cria… quando inicia o tomcat e @PreDestroy-Deleta…quando para o tomcat, a anotation @ApplicationScoped - Resolveria o problema de concorrência para gerar esses arquivos?

Ats,

Lucas_Cavalcanti

não… @ApplicationScoped não resolve problema de concorrência, pois é uma instância só compartilhada pra aplicação inteira…

@RequestScoped não passa pelos métodos mesmo?

H

Mudei a anotação para @RequestScoped e eles não passam pelo @PostConstruct e @PreDestroy, só entra nos métodos quando colaca a anotação @ApplicationScoped
Era para funcionar com @RequestScoped certo?

Lucas_Cavalcanti

vc está usando essa sua classe anotada em algum lugar da requisição?

acabei de testar aqui no blank-project do vraptor e ele só não chama os construct e destroy se vc não usar a classe.

H

Então as chamadas estão assim: o client chama a uri (“gestao/endereco/exportar”), dentro da classe GestaoController no método que retorna “FileDownload” para o client
Eu instacio o objeto ExportarBussiness e chamo o seu método que retorna um “file” para download certo.
Essa classe ExportarBussiness que está marcada com @Componet e @RequestScoped.
Pelo que eu entedi eu tenho que instanciar o Objeto “ExportarBussiness” no contrutor da Classe GestaoController?

Lucas_Cavalcanti

não, vc não pode instanciar a classe, vc tem que recebê-la no construtor, assim o VRaptor gerencia e chama os métodos create e destroy.

public GestaoController(...., ExportarBusiness business) {
    //...
    this.business = business;
}
H

Lucas, realmente era só receber no construtor…
Agora deu certo …
Muito Obrigado pela ajuda,Mais uma vez rs…!

Ats.

B

Poxa, a pergunta que deu origem ao tópico ficou sem resposta. Também gostaria de algum tutorial ou algo que desse o pontapé inicial para webservices com VRaptor. Agradeço qualquer colaboração =)

Lucas_Cavalcanti

depende do que vc quer dizer com webservice, qualquer lógica de um controller é um webservice.

vc pode receber e retornar xmls ou jsons em qualquer lógica de um controller

B

Gostaria de mexer com SOAP e Webservice mesmo. Lucas, recomenda alguma leitura inicial?

Lucas_Cavalcanti

bom, isso seria uma coisa alheia ao vraptor, ou seja, o que vc faria com SOAP independe do que vc faria com o VRaptor e vice versa…

pode usar qualquer tutorial genérico de SOAP.
deve ter vários tópicos falando sobre isso aqui no guj, ou mesmo no google, não sou a melhor pessoa pra te ajudar nisso, desculpe

B

Que isso, agradeço só pela atenção.

O lance é que nunca mexi com WS, e tenho que fazer um trabalho para faculdade, uma aplicação WEB que também disponibilizará serviços utilizando SOAP. E desde que conheci o VRaptor não abro mão de fazer as coisas com ele =). Como o container que utilizo com ele é o Spring, e o existe Spring-WS, gostaria de algum exemplo que mostrasse como unir os dois.

Pelo que li superficialmente, um serviço criado com spring-ws é um servlet mapeado no web.xml, mas o VRaptor intercepta todas as requisições. Então gostaria de um exemplo unindo VRaptor e Spring-WS.

Lucas_Cavalcanti

não precisa fazer nada do lado do VRaptor, é só usar o Spring-WS normalmente.

só não pode ter uma lógica no VRaptor que responde pra mesma url que o WS

B

Valeu, Lucas. Obrigado pela ajuda. =)

C

Pois é, eu estou tentando descobrir como fazer isso ainda, ou seja usar os controllers do VRaptor para serem acessados diretamente por Webservices SOAP, que por sua vez seria acessados até por aplicações CLIPPER. Ninguem teve novidades a respeito ainda?

Lucas_Cavalcanti

vc quer usar o VRaptor pra expor serviços SOAP? ou para ser acessado normalmente via HTTP / REST?

C

Lucas, eu tenho por exemplo o PedidoController, com os metodos adiciona e busca implementados e funcionando.

Eu precisaria expor estes métodos pra uma aplicação escrita em CLIPPER.

Pensei então em usar o JBOSSWS, que já usamos para outras coisas, e o CLIPPER acessaria via HTTP este webservice, que por sua vez acessaria diretamente os controllers já implementados.

Lucas_Cavalcanti

bom, vc pode continuar usando o controller da mesma maneira, fazendo um POST com parâmetros, da mesma forma que se fosse no browser,

ou vc pode adaptar o controller pra receber e enviar um JSON/XML.

para isso vc consegue usar:

@Deserializes("application/xml")
public void adiciona(Pedido pedido) {
   //...

   result.use(Results.xml()).from(umObjeto).serialize();
}

o pedido precisa estar em um formato comportado, como:

<pedido>
    <propriedade>valor</propriedade>
</pedido>
C

Lucas, e como através do XML o pedido seria deserializado com os tipos corretos?

Sobre os controllers na verdade então eu teria que criar um clone de cada controller, porém entregando e recebendo XML?

Outra coisa, como o controller saberá que aquela string e/ou XML recebido é um objeto Pedido?

Lucas_Cavalcanti

o VRaptor usa as informações que vc passou pra ele.

no método adiciona vc tá recebendo um parâmetro do tipo Pedido, então ele sabe que tem que deserializar um pedido. O nome do parâmetro é pedido, então a raiz do xml tem que ser pedido. A partir daí ele vai batendo as tags do xml com as propriedades e criando o objeto.

vc não precisa criar um clone de tudo, só do que vai ficar exposto como serviço.

mesmo assim, dá pra aproveitar os métodos do controller normal, e usar um método só:

@Consumes("application/xml", "application/x-www-form-urlencoded") // e não @Deserializes como eu tinha feito antes
public void adiciona(Pedido pedido) {

    result.use(Results.representation()).from(objeto).serialize();
}

fazendo isso, se a requisição for por um formulario http, ele funciona com http, se vc passou o content-type da requisição como application/xml, ele deserializa o xml. E na hora de responder, se for form normal, ele redireciona pra jsp, se tiver o header Accept: application/xml serializa como xml.

o que vc pode fazer, é separar as lógicas de negócio em outras classes, e ter dois controllers que usam essas lógicas, um com a interface web normal, e outra com a interface REST (HTTP).

C

acho que entendí Lucas.

Vou testar e depois aviso aqui.

Muito obrigado!

Criado 17 de dezembro de 2010
Ultima resposta 14 de fev. de 2012
Respostas 34
Participantes 5