Rest + vraptor

24 respostas
J

Olá Pessoal,
Preciso implementar uma solução REST entre duas aplicações (App Server e App Cliente)

Estou usando o VRAPTOR e do lado da app servidora estou conseguindo resolver a situação.

Minha classe teste está assim:

@Resource
public class ProxyUsuarioController {

	private final Result result;
	private final Status status;
	private final UsuarioDAO usuarioDAO;

	public ProxyUsuarioController(Result result, Status status, UsuarioDAO usuarioDAO) {
		this.result = result; 
		this.status = status;
		this.usuarioDAO = usuarioDAO;
	}

	@Public @Get("/xml/usuario/epico/login/{usuarioEpico.usuarioNome}/{usuarioEpico.senha}")
	public void login(UsuarioEpico usuarioEpico) {
		
		UsuarioEpico _usuarioEpico = usuarioDAO.loginEpico(usuarioEpico);
		
		if(_usuarioEpico != null){
						
			result.use(xml()).from(_usuarioEpico).serialize();
			
		}else{
			
			status.notFound();
			
		}
		
	}
	
}

É uma classe de autenticação, ou seja, apenas via app servidora será possível logar (exemplo de regra de negócio).

Está me fornecendo o seguinte xml quando requisitada via navegador.

<usuarioEpico>
 <id>???</id>
 <ativo>true</ativo>
 <usuarioNome>???</usuarioNome>
</usuarioEpico>

Perfeito, desse lado está ok, mas como seria a action da aplicação cliente, ou seja, como consumir este xml usando a eng do próprio VRAPTOR?

Cheguei a pegar um modelo exemplo (https://github.com/caelum/restfulie-java) disponível mas está usando métodos depreciados e acho que talvez haja algo já aprimorado.

Abraços,
Jsign

24 Respostas

L

Você pode consumir esse xml usando qqer cliente http.

No restfulie, tentou usar:

Response response = Restfulie.at("url completa").get();

UsuarioEpico usuario = response.getResource();

se não funcionar, vc pode usar o Restfulie.custom()

a doc tá aqui: https://github.com/caelum/restfulie-java/wiki

J

Olá Lucas, em primeiro lugar, obrigado!

Estou usando a lib vraptor-3.4.0.jar

Não possuo o metodo estátido Restfulie.at

Também não possuo a classe RestClient apenas RestClientException.

sabe de devo adicionar algum jar complementar?

L

o Restfulie server está dentro do VRaptor, mas o Restfulie-client é outro jar. Deveria estar lá no github o jar do client, ou no maven.

J

Nota: Na documentação recomendam o uso da versão 3.3.0.

L

O restfulie client não tem nada a ver com o VRaptor, são projetos totalmente separados.

aqui o jar do client (no maven)
http://repo1.maven.org/maven2/br/com/caelum/restfulie/1.0.1/restfulie-1.0.1.jar

J

Opa, beleza.
Vou adicionar o jar e notifico mas acho que não haverá problema mais.

Obrigado Lucas.
Jsign

J

Olá Lucas, ainda estou com problema por falta da classe Pluralizer.

Vou baixar e ver se resolve.

String url = E.DESENV_URL+"/server/xml/login/sgv/4969@";

System.out.println("url :: " + url);
		
Response response = Restfulie.at(url).get();

................... 

Caused by: java.lang.NoClassDefFoundError: org/jvnet/inflector/Pluralizer
	at br.com.caelum.restfulie.Restfulie.custom(Restfulie.java:47)
	at br.com.caelum.restfulie.Restfulie.at(Restfulie.java:61)
	at br.com.caelum.restfulie.Restfulie.at(Restfulie.java:71)
	at br.com.brabus.epico.component.rest.server.ComsumerUsuarioController.login(ComsumerUsuarioController.java:22)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:61)
	... 46 more
Caused by: java.lang.ClassNotFoundException: org.jvnet.inflector.Pluralizer
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1523)
	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
	... 55 more
J

Baixei o Puralizer e passou pro próximo erro de dependencias: org.apache.http.HttpRequest
Vou baixar as dependencias conforme forem aparecendo e fecho o post assim que ok.

Abraços,
Jsign

L

se você usar o maven, o ivy, ou coisa do tipo ele baixa as dependências pra vc.

J

Estou protelando para implantar o maven mas vou fazer isso sim.
Sabe de um bom material/tutorial?

Abraços,
Jsign

J

Achei um seu mesmo, vou ver se consigo por em prática.


Abraços,
Jsign

J

Olá Lucas e gujeiros,

Os ajustes veem sendo feitos e estou ‘quase lá’ na implementação rest da minha aplicação.
Estou com o seguinte problema relacionado:

Na minha aplicação cliente (consome xml) há uma action que recebe valores via post e deveria levar os mesmos a minha aplicação servidora (disponibiliza xml) também via post.
Dos dois lados fiz as anotações pertinentes ao método @Post.
Mas, aparentemente, a aplicação servidora não consegue converter em objeto os dados enviados.
Algém saberia me ajudar?

Servidora

@Resource
public class ProxyUsuarioController {

	private final Result result;
	private final UsuarioDAO usuarioDAO;

	public ProxyUsuarioController(Result result, UsuarioDAO usuarioDAO) {
		this.result = result; 
		this.usuarioDAO = usuarioDAO;
	}

	@Public @Post("/server/xml/login")
	public void login(UsuarioEpico usuarioEpico) {

		result.use(xml()).from( usuarioDAO.loginEpico( usuarioEpico) ).serialize();
		
	}
	
}

Cliente

@Resource
public class ComsumerUsuarioController {
	
	RestClient restfulie;
	
	public ComsumerUsuarioController(){
		
		restfulie = (RestClient) Restfulie.custom();
		
		restfulie.getMediaTypes().register(new XmlMediaType().withTypes(UsuarioEpico.class));
		
	}
	
	@Public @Post("/cliente/xml/login")
	public void login(UsuarioEpico usuarioEpico){
		
		System.out.println( usuarioEpico.getUsuarioNome() + " :: " +  usuarioEpico.getSenha() );
		
		Response response = restfulie.at(E.DESENV_URL+"/server/xml/login").accept("application/xml").as("application/xml").post(usuarioEpico); // o pau da aqui
		
		... 
		
	}
	
	@Public @Get("/cliente/xml/login")
	public void logar(){}
	
}

Exeption

....
Caused by: java.lang.NullPointerException
	at br.com.brabus.epico.dao.acesso.UsuarioDAO.loginEpico(UsuarioDAO.java:334)
	at br.com.brabus.epico.component.rest.server.ProxyUsuarioController.login(ProxyUsuarioController.java:24)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:61)
	... 47 more

nota: Transferi a implementação do Maven para outro post separando as necessidades.

L
Caused by: java.lang.NullPointerException  
    at br.com.brabus.epico.dao.acesso.UsuarioDAO.loginEpico(UsuarioDAO.java:334)

o que tem nessa linha? o que pode ser null nela?

J

Olá Lucas,

Vou postar a método/chamada e o método que contém a linha onde ocorre erro.

Chamada:

@Resource
public class ProxyUsuarioController {

	private final Result result;
	private final UsuarioDAO usuarioDAO;

	public ProxyUsuarioController(Result result, UsuarioDAO usuarioDAO) {
		this.result = result; 
		this.usuarioDAO = usuarioDAO;
	}

	@Public @Post("/server/xml/login/teste")
	public void login(UsuarioEpico usuarioEpico) {
		
		result.use(xml()).from( usuarioDAO.loginEpico(usuarioEpico) ).serialize(); // call
		
	}
	
}

Método:

public UsuarioEpico loginEpico(UsuarioEpico usuarioEpico){ // chega nulo
				
		try {
			
			Class.forName(E.ORACLE_DRIVER);
				
			Connection con = null;
			
			con = DriverManager.getConnection(E.ORACLE_STR_CONN, usuarioEpico.getUsuarioNome().toUpperCase(), usuarioEpico.getSenha().toUpperCase());
				
			if(con instanceof Connection){
				
				con.close();
				
				return (UsuarioEpico)mysqlSession.createCriteria(UsuarioEpico.class).add(Restrictions.eq("usuarioNome",usuarioEpico.getUsuarioNome())).uniqueResult();
				
			}
		
		} catch (Exception e) {

			E.exToMsg(e, "[ACESSO] FALHA NA CONEXAO DO O USUARIO "+usuarioEpico.getUsuarioNome().toUpperCase()+"\n\r" + "ERRO TRACE :: \n\r" +e.getStackTrace().toString());
		
		}
		
		return null;
		
	}

Abraços,
Jsign

L

você está passando um usuarioEpico pra requisição? Como?

J

Via restfulie.at.post
Achei que o post ( usuarioEpico ) encarregava-se de enviar o objeto parametro para a action/url at( url ). Não é assim?

Response response = restfulie.at(E.DESENV_URL+"/server/xml/login").accept("application/xml").as("application/xml").post(usuarioEpico);

Abraços, jsign

L

se você quer quer funcione assim, o lado do servidor precisa estar esperando receber um xml (e não form parameters como é o padrão)…

anote o método do controller com:

@Consumes("application/xml")
J

Ok, vou testar.
Obrigado Lucas.

L

vc ainda não colocou o @Consumes no método do controller da app servidora

J

Olá Lucas, removi parte do conteúdo antes da sua ultima postagem pra não saturar o tópico.

No método de login (abaixo) imprimi o retorno do response.

@Public @Post("/cliente/xml/login")
	public void login(UsuarioEpico usuarioEpico){
		
		Response response = restfulie.at("http://xxxxxxxxxxxx:8080/epico/server/xml/login").accept("application/xml").as("application/xml").post(usuarioEpico);
		
		System.out.println( response.getContent() );
		
		UsuarioEpico ue = (new EXmlReader()).get(UsuarioEpico.class, "usuarioEpico", response.getContent());
		
		result.include( "usuarioEpico", ue  );

		E.forward(result, "login/inicio.jsp");
		
	}

impressão response:

<html><head><title>Apache Tomcat/7.0.22 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 500 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Exception report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The server encountered an internal error () that prevented it from fulfilling this request.</u></p><p><b>exception</b> <pre>java.lang.IllegalArgumentException: XPP3 pull parser library not present. Specify another driver. For example: new XStream(new DomDriver())
	com.thoughtworks.xstream.io.xml.XppDriver.loadLibrary(XppDriver.java:62)
	com.thoughtworks.xstream.io.xml.XppDriver.createReader(XppDriver.java:43)
	com.thoughtworks.xstream.io.xml.XppDriver.createReader(XppDriver.java:49)
	com.thoughtworks.xstream.XStream.fromXML(XStream.java:861)
	br.com.caelum.vraptor.deserialization.XStreamXMLDeserializer.deserialize(XStreamXMLDeserializer.java:58)
	br.com.caelum.vraptor.interceptor.DeserializingInterceptor.intercept(DeserializingInterceptor.java:87)
	br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.brabus.epico.interceptor.AdmScope.intercept(AdmScope.java:34)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.brabus.epico.interceptor.AdmAcesso.intercept(AdmAcesso.java:47)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:87)
	br.com.caelum.vraptor.core.LazyInterceptorHandler.execute(LazyInterceptorHandler.java:59)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:44)
	br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
	br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
</pre></p><p><b>note</b> <u>The full stack trace of the root cause is available in the Apache Tomcat/7.0.22 logs.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.22</h3></body></html>

Causa raiz do problema:

Caused by: com.thoughtworks.xstream.io.StreamException:  : Premature end of file.
	at com.thoughtworks.xstream.io.xml.DomDriver.createReader(DomDriver.java:86)
	at com.thoughtworks.xstream.io.xml.DomDriver.createReader(DomDriver.java:66)
	at com.thoughtworks.xstream.XStream.fromXML(XStream.java:853)
	at com.thoughtworks.xstream.XStream.fromXML(XStream.java:845)
	at br.com.brabus.epico.infra.EXmlReader.get(EXmlReader.java:18)
	at br.com.brabus.epico.infra.LoginController.login(LoginController.java:43)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:61)
	... 44 more
Caused by: org.xml.sax.SAXParseException: Premature end of file.
	at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
	at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
	at com.thoughtworks.xstream.io.xml.DomDriver.createReader(DomDriver.java:79)
	... 54 more

Minha action servidora

@Public @Post("/server/xml/login") @Consumes("application/xml")// http://xxxxxxxxxxxx:8080/epico/server/xml/login
	public void login(UsuarioEpico usuarioEpico) {
		
		System.out.println( usuarioEpico.getUsuarioNome() ); // não chegou aqui
		
		result.use(xml()).from( usuarioDAO.loginEpico(usuarioEpico) ).serialize();
		
	}

Abraços
Jsign

L

a causa raiz é a do servidor?

ele reclamou do xpp parser, tenta baixar o jar dele e por no classpath…

e seria legal tentar ver qual é o xml que chegou no servidor. (log de debug no restfulie, ou tenta fazer um servlet filter que imprime o request.getInputStream())

J

Olá Lucas,
Ok vou fazer isso já, apanhei um pouco do maven e estou baixando as dependências conforme os erros.
Mais adiante eu volto nele.

L

coloque esse jar:
http://repo1.maven.org/maven2/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar

J

Matou Lucas, era isso mesmo.
Supinpa.

Criado 14 de dezembro de 2011
Ultima resposta 21 de dez. de 2011
Respostas 24
Participantes 2