[RESOLVIDO] Consumindo serviço do vraptor via C#

Olá pessoal,

Estou tendo um problema com essa união. Tenho um serviço em vraptor e preciso que este seja consumido por um cliente em C#.

Entretanto, esse cliente em C# não está utilizando o restfulie, está fazendo usando o HttpWebRequest.

De maneira análoga, pedi para que o mesmo anexasse ao HTTP a estrutura do objeto que necessito em formato XML (este serviço é um post).

Só que diversas foram as maneiras que tentamos e não obtivemos sucesso.

Alguém que possa nos ajudar?

Obrigado de antemão.

Mas o que está ocorrendo, o VRaptor não está conseguindo desserializar o que voce está mandando para o seu objeto?

Olá alias, muito obrigado pela resposta.

Bom, eu não estou conseguindo comunicação do meu cliente em C# com o meu servidor vraptor.

Como disse, esse cliente não está utilizando o restfulie, sendo assim, ele usa a forma “básica” de comunicação (eu não programo em C#, não sei muitos detalhes).

Então eu queria saber como que eu consigo garantir que o meu cliente em C# possa se comunicar com o meu server em vraptor.

O que ele deve estar mandando e de que maneira para que possa chegar um objeto preenchido até o meu método dentro do Controller do vraptor.

Espero que tenha ficado mais claro. Obrigado mais uma vez.

Entao, o VRaptor vai expor o seu método através de uma URL, correto? Dessa forma é perfeitamente possível você acessá-lo através do C# (ou qualquer outra coisa onde voce consiga fazer uma requisicao HTTP).

Você disse que está enviando XML para o seu serviço. O seu método está parametrizado para receber XML, anotado com, salvo engano, @Accepts?

Suponho que voce está recebendo um objeto ai do seu modelo, correto? Considerando que sim, bom, entao basta serializar o objeto do lado C# (que tenha a mesma estrutura do objeto que voce espera) para XML, escrever ele na requisicao HTTP e mandar. Nâo tem muito segredo, o que voce disse estar fazendo é o correto. E com o HttpWebRequest do C# dá pra fazer isso também.

Se puder, coloca ai o seu codigo C# e o do VRaptor, por favor.

se o erro que está dando é o de falha de comunicação, verifique se o servidor com o vraptor está de pé, e que a porta em que ele esteja subido (ex. 8080) esteja aberta pra comunicação externa…

e verifique tb se a máquina do cliente em C# tem acesso a isso.

qualquer cliente HTTP é suficiente pra consumir serviços com o VRaptor

alias e Lucas, obrigado por tentarem me ajudar.

alias, eu não encontrei essa anotação que você me passou (@Accepts). Contudo, ele tentou todas as maneiras possíveis de envio via C#. Para resumir, ele gera o XML em bytes, anexa no HTTP e envia.

Lucas, a comunicação está existindo, pois todo envio chega no servidor, porém ele sempre recebe um erro 404, como se não tivesse conseguindo fechar uma comunicação.

Eu não tenho o código em C#, mas irei postar o código em Java.

@Post
@Consumes
@Path( "/lancaLoteGuiaEmConta" )
public void create( LoteGuiaDto loteGuia ) {
...
}

Pesquisando eu vi esse site. O código é bem parecido.

Mais uma vez, obrigado.

[quote=bland]alias e Lucas, obrigado por tentarem me ajudar.

alias, eu não encontrei essa anotação que você me passou (@Accepts). Contudo, ele tentou todas as maneiras possíveis de envio via C#. Para resumir, ele gera o XML em bytes, anexa no HTTP e envia.

Lucas, a comunicação está existindo, pois todo envio chega no servidor, porém ele sempre recebe um erro 404, como se não tivesse conseguindo fechar uma comunicação.

Eu não tenho o código em C#, mas irei postar o código em Java.

@Post
@Consumes
@Path( "/lancaLoteGuiaEmConta" )
public void create( LoteGuiaDto loteGuia ) {
...
}

Pesquisando eu vi esse site. O código é bem parecido.

Mais uma vez, obrigado.[/quote]

Ops, a anotação é @Consumes que voce já está usando, me desculpe (igualzinho a @Accepts né :lol: )

Cara o erro 404 indica que o recurso não está sendo encontrado no servidor. A pergunta é besta mas a URL que ele está invocando está correta? “nomedasuaapp/lancaLoteGuiaEmConta”? Do lado do VRaptor sua classe está anotada com @Resource?

se vc usou o @Consumes do vraptor (e não o do jax-rs) esse código deveria funcionar vc gerando a requisição:

POST http://url-da-app/contexto/lancaLoteGuiaEmConta   
Content-Type: application/xml
Accept: application/xml
<loteGuia>
   ...
</loteGuia>

alias, a URL está correta, pois consigo consumí-la usando um cliente restfulie em Java. O Controller está anotado com @Resource.

Lucas, foi exatamente assim que fizemos o teste. E nada aconteceu. O @Consumes é do vraptor mesmo.

Eu tenho outros serviços disponíveis cujo cliente consegue consumir. Abaixo:

@Resource
public class PacienteController {

@Get
@Path( "/paciente/{identificador}" )
public void buscar( Long identificador ) {
...
}

@Get
@Path( "/paciente/elegibilidade/{convenio}-{servico}" )
public void elegibilidade( Long convenio, String servico ) {
...
}

}

Esses serviço acima conseguem ser acessados pelo cliente em C#. Porém, quando o mesmo tenta fazer um post do XML para o serviço de LoteGuia, ele não consegue.

Tem mais alguma coisa que eu precise informar para vocês para que possam me ajudar a resolver esse problema?

Dúvida: da maneira que está o meu serviço que recebe um post estaria aceitando XML, correto?

vc tá mandando o header Content-Type na requisição? a resposta dela é 404?

o vraptor só dá esse 404 se a URL estiver errada ou vc tenha feito o result.notFound()

outra coisa que pode ter acontecido é não existir o jsp corrrespondente ao método do controller

Lucas,

Posso estar enganado quanto ao código do erro. Por vezes retornou 404, em outros testes retornou 403. Como foram vários testes, posso estar enganado quanto ao código do erro.

O Content-Type está sendo passado sim, como XML. E dentro dos métodos eu não estou usando o result.notFound().

Um ponto que você tocou e que achei interessante foi que realmente não existe página JSP. Como a ideia é ser uma aplicação para dispor de serviços, então não criei página alguma.

Essa página se torna necessária? Se sim, porque? E onde está página deve estar? Qual a estrutura de pastas que o vraptor segue?

Muito obrigado pela sua ajuda.

[quote=bland]Lucas,

Posso estar enganado quanto ao código do erro. Por vezes retornou 404, em outros testes retornou 403. Como foram vários testes, posso estar enganado quanto ao código do erro.

O Content-Type está sendo passado sim, como XML. E dentro dos métodos eu não estou usando o result.notFound().

Um ponto que você tocou e que achei interessante foi que realmente não existe página JSP. Como a ideia é ser uma aplicação para dispor de serviços, então não criei página alguma.

Essa página se torna necessária? Se sim, porque? E onde está página deve estar? Qual a estrutura de pastas que o vraptor segue?

Muito obrigado pela sua ajuda.[/quote]

O comentario do fessor Lucas foi pertinente, o VRaptor sempre vai buscar o JSP ref. aquele controller/metodo, como voce não deseja isso, voce poderia usar

result.use(Results.nothing())

que o VRaptor só vai retornar HTTP 200 (OK) (estou supondo que o seu metodo não retorna nada para o cliente). O que ocorre é que o result precisa ir pra algum lugar, e por padrão é o JSP. Você tambem pode devolver sua resposta em xml ou json.

Procede lucas?

ela não é necessária, mas vc precisa usar o result pra ir pra algum lugar…

tipo algo como:

result.use(Results.xml()).from(objeto).serialize();

alias, obrigado mais uma vez. Eu faço uso do result.use( Results.xml() ) e isso funciona para os métodos @Get. Como deveria ser. Porém, para o método @Post eu não preciso de um retorno, apenas informar o “ok”, como já faço.

Para retornar dos métodos @Get eu estou usando como o Lucas mostrou. E está funcionando normalmente.

Contudo o grande problema está na chegada o método @Post, onde não estamos conseguindo fazer com que a requisição chegue até o seu destino. Isso, pra mim, é o grande problema. E é uma coisa que não consigo entender o motivo de não estar funcionando.

Pensei que poderia ser na implementação C#, mas, apesar de não programar em C#, eu pesquisei e vi que os exemplos que eu encontrava eram iguais ou muito parecidos com a implementação do cliente.

Fiz uma análise, também, do XML passado por parâmetro, e o mesmo estava correto. Enfim, chegou um momento em que eu não sabia mais o que fazer e nem para onde ir. Por isso mandei essa mensagem aqui no GUJ.

Existe mais alguma coisa em que eu esteja me passando? E que possa surtir algum efeito? Nem que seja mudar o erro (risos).

Muito obrigado pela tentativa de ajuda de vocês.

Abraço!

tem alguma chamada ao result nesse método com POST?

Lucas, tem sim:

Eu não tenho o código em mãos agora. Mas acredito que só tenho esse. Fora, claro, quando dá um erro e eu chamo o badRequest…

Abraço!

ok, tenta então fazer o seguinte… instala o poster no seu Firefox (uma extensão) e tenta simular a requisição ao sistema, pra tentar ver se consegue simular o que está acontecendo…

https://addons.mozilla.org/pt-br/firefox/addon/poster/

preencha a URL, content-type e o corpo da requisição com o xml e veja se está chegando no método.

se vc conseguir fazer a requisição assim é algum problema no código do C#… e isso provavelmente vai te ajudar a descobrir o que está errado.

Olá Lucas, tudo bem?

Instalei o Poster, como pediu, e fiz uma simulação. Estou encontrando um erro que não consigo resolver.

Você sabe dizer qual o formato que deveria estar sendo passada a data?

Obrigado mais uma vez pela ajuda.

provavelmente sem a hora… talvez 30/08/2012, dependendo do locale do servidor.

vc pode escrever um converter do xstream, de qqer modo, pra tentar sobrescrever esse formato.

Olá Lucas,

Deu certo. Adicionei um converter:

String[] formats = { "dd/MM/yyyy HH:mm:ss", "dd/MM/yyyy" };
XStream stream = super.getXStream();
stream.registerConverter(new DateConverter( "yyyy-MM-dd", formats ) );

E ele passou a pegar a data corretamente.

E usando o Poster, eu consegui identificar esse problema e conseguir manter uma comunicação. Sendo assim, eu só posso atestar que o problema é no cliente em C#, pois consegui manter uma comunicação com um simples requisitor HTTP passando um XML em anexo.

Mais uma vez, muito obrigado pela sua ajuda.