RESTFullie Client-Side

13 respostas
bland

Hey guys,

Tenho uma dúvida quanto a utilização do RESTFullie. Eu estou fazendo a implementação de um WebService para a integração entre dois projetos. Porém, lendo um pouco, vi que posso utilizar o vRaptor, com o RESTFullie, para solucionar o mesmo problema de integração de forma muito mais elegante.

A dúvida seria: como fazer o consumo de um serviço RESTFull (similar ao consumo de um serviço de um WebService) usando o RESTFullie?

Fiz algumas pesquisas e não achei nada ligado. Encontrei um exemplo do Adriano Almeida no GitHub mas nada muito claro de como fazer isso. Hoje eu tenho alguns frameworks que geram as classes com base nos .wsdl, ou seja, eu teria algo parecido com a utilização do RESTFullie? Ou gerar o cliente na mão, criando classe a classe? Como seria isso?

Obrigado.

Abraço.

Fabiano Almeida.

13 Respostas

Lucas_Cavalcanti

Olá Fabiano,

exemplos de como usar o restfulie:

consumir o serviço vc pode fazer com qualquer cliente http, e o restfulie client deixa esse trabalho mais fácil.

não existe wsdl no REST, mas existe um parecido: o WADL. O Restfulie+VRaptor ainda não tem suporte a isso.

A boa notícia é que vc não vai precisar gerar várias classes para consumir o serviço: vc só precisa do Restfulie. Daí vc pode gerar suas classes só se preocupando com a lógica do negócio, e não com a infra.

[]'s

bland

Lucas,

Acho que estou me sentindo um pouco perdido e gostaria da sua ajuda.

Criei um serviço no servidor onde o cliente é:
@XStreamAlias( "client" )
public class Client {

	private String name;

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	
}
E o serviço...
@Resource
public class ClientsController {
 
 @Autowired
 private ClientDao dao; 

 Result result;
 
 public ClientsController(Result result) {
  this.result = result;
 }
 
 
 @Path("/cliente.xml")
 @Get
 public void list(){
  List clientes =  dao.allClients();
  result.use(Results.xml()).from(clientes.get(0)).serialize();
  
 }
}
E criei no meu cliente a classe:
@Test( groups = "V.1.0" )
public class ExampleTests {

	@Test
	public void shouldBeTheSameClient() throws Exception {

		Resources resources = Restfulie.resources();
		resources.configure( Client.class );

		String fromXml = Restfulie.resource( "http://10.32.2.17:8080/WebServiceRest/cliente.xml" ).get().toString();
		
		Client client = ( Client ) resources.getDeserializer().fromXml( fromXml );

		Assert.assertNotNull( client );
		Assert.assertNotNull( client.getName() );
		Assert.assertEquals( client.getName(), "marcus" );
	}
	
}
Depois de executar esse teste por algumas vezes, o fiz usando o Debug e quando faço o inspect dessa linha:
Restfulie.resource( "http://10.32.2.17:8080/WebServiceRest/cliente.xml" ).get()
está me retornando um erro:
com.thoughtworks.xstream.mapper.CannotResolveClassException: client : client at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:68) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:71) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:86) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:96) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38) at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:52) at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29) at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:136) at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:33) at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:923) at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:909) at com.thoughtworks.xstream.XStream.fromXML(XStream.java:853) at com.thoughtworks.xstream.XStream.fromXML(XStream.java:845) at br.com.caelum.restfulie.XStreamDeserializer.fromXml(XStreamDeserializer.java:49) at br.com.caelum.restfulie.http.DefaultResponse.getResource(DefaultResponse.java:78) at br.com.caelum.restfulie.EntryPointService.get(EntryPointService.java:137) at br.com.scmba.ws.lancamento.item.conta.genhio.domain.controller.ExampleTests.shouldBeTheSameClient(ExampleTests.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 org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:641) at org.testng.internal.Invoker.invokeMethod(Invoker.java:677) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:850) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1154) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:137) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:121) at org.testng.TestRunner.runWorkers(TestRunner.java:1108) at org.testng.TestRunner.privateRun(TestRunner.java:737) at org.testng.TestRunner.run(TestRunner.java:596) at org.testng.SuiteRunner.runTest(SuiteRunner.java:315) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:310) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:272) at org.testng.SuiteRunner.run(SuiteRunner.java:221) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1027) at org.testng.TestNG.runSuitesLocally(TestNG.java:964) at org.testng.TestNG.run(TestNG.java:896) at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:89) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:144)

O que posso estar fazendo de errado?

Obrigado!!!

Lucas_Cavalcanti

vc precisa configurar o mediaType, adicionando o mapeamento para o cliente:


(método setUp)

bland

Lucas,

Eu já tinha visto essa classe, mas o método Restfulie.custom() não consta na lib que tenho na minha aplicação (restfulie-java-client-1.0.0-beta2.jar).

Eu consegui de uma outra forma, talvez até menos elegante:
Resources server = Restfulie.resources();
		server.configure( Client.class );

		Client client = server.entryAt( "http://10.32.2.17:8080/WebServiceRest/client.xml" ).accept( "application/xml" ).get();

Mas qual seria a maneira correta? Vi que com a utilização da classe de exemplo você registra de uma única vez as diversas classes que você irá utilizar. Portanto, como proceder já que o método custom() não existe?

Abraço e obrigado!

Lucas_Cavalcanti

sugiro que vc atualize para o beta4 e siga as classes de exemplo para saber como fazer.

essa funcionalidade que eu falei não existe no beta2

bland

Lucas,

Mais uma vez obrigado pela ajuda, porém, acho que não entendi muito bem o que disse.

Fiz uma busca em todas as pastas do link que me passou e não encontrei a versão beta4, nem mesmo no link do projeto: http://code.google.com/p/restfulie/downloads/list

Onde estaria essa lib? Existe algum repositório para ela?

Muito obrigado.

Abraço!

R

Esta nesse repositório:

Lucas_Cavalcanti

o beta4:
http://code.google.com/p/restfulie/downloads/detail?name=restfulie-1.0.0.beta4.jar&can=2&q=

o link que eu passei antes era do exemplo de como usar.

[]'s

bland

Rafael, obrigado!

Lucas, baixei pelo GitHub a versão beta4.

Tenho um novo problema. Fiz a implementação que você sugeriu:
RestClient restfulie = Restfulie.custom();
		restfulie.getMediaTypes().register( new XmlMediaType().withTypes( Client.class, Item.class ) );

		Response response = restfulie.at( "http://10.32.2.17:8080/WebServiceRest/client" ).accept( "application/xml" ).get();

		Client cliente = response.getResource();

Só que eu estou tendo um problema no retorno do ApacheResponse.getContent(), que está me retornando "" (vazio). Ou seja, isso está impactando na desserialização do objeto que está sendo passado pelo servidor.

Saberia dizer como posso resolver esse problema?

Obrigado mais uma vez.

Abraço!

R
bland:
Rafael, obrigado!

Lucas, baixei pelo GitHub a versão beta4.

Tenho um novo problema. Fiz a implementação que você sugeriu:
RestClient restfulie = Restfulie.custom();
		restfulie.getMediaTypes().register( new XmlMediaType().withTypes( Client.class, Item.class ) );

		Response response = restfulie.at( "http://10.32.2.17:8080/WebServiceRest/client" ).accept( "application/xml" ).get();

		Client cliente = response.getResource();

Só que eu estou tendo um problema no retorno do ApacheResponse.getContent(), que está me retornando "" (vazio). Ou seja, isso está impactando na desserialização do objeto que está sendo passado pelo servidor.

Saberia dizer como posso resolver esse problema?

Obrigado mais uma vez.

Abraço!

Ohei o código desse método:

public String getContent() {
		if (entity == null) {
			return "";
		}
		try {
			long len = entity.getContentLength();
			if (len != -1 && len < 10 * 1024 * 1024) {
				return EntityUtils.toString(entity);
			} else {
				return "";
			}
		} catch (IOException ex) {
			throw new RestfulieException("Unable to parse response content", ex);
		}
	}

Ele retorna vazio em duas situações. Te aconselho a clonar o repositório do github.
E colocar verificações no código para verificar qual dessas situações está ocorrendo.

Lucas_Cavalcanti

bland, o beta4 estava com esse bug mesmo…

testa, por favor, com esse snapshot do beta5, com o bug corrigido

Abraços

progoz

Lucass,

Fiquei com uma dúvida, no googlecode tem duas libs, restfulie-java e o restfulie-java-client, no client-side não deveria ser a lib restfulie-java-client? ou não tem nada a ver ? como que funciona essas libs ?

Abraços

Lucas_Cavalcanti

foi só uma troca de nome.

o restfulie é o restfulie-client, pois o server está dentro do VRaptor

[]'s

Criado 26 de janeiro de 2011
Ultima resposta 29 de jan. de 2011
Respostas 13
Participantes 4