Estou participando da atividade de migrar a arquitetura de um sistema que utiliza JSF com managed bean para uma arquitetura orientada a serviço.
Tinha algumas dúvidas a respeito das anotações que eram utilizadas no service, e por esse motivo decidi escrever esse post. Vamos iniciar pelo código 😀
Crie um projeto utilizando o artifact id: maven-archetype-webapp. Adicione as seguintes dependências no pom.xml.
<repositories> <repository> <id>JBoss repository</id> <url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jaxrs</artifactId> <version>2.2.1.GA</version> <scope>provided</scope> </dependency> </dependencies>
Para esse exemplo estou utilizando a implementação Resteasy do JAX-RS com o servidor de aplicação WildFly 16.
Adicione o seguinte conteúdo no web.xml
<web-app> <display-name>Aplicação Rest Java Exemplo</display-name> <context-param> <param-name>resteasy.scan</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>resteasy.servlet.mapping.prefix</param-name> <param-value>/rest</param-value> </context-param> <listener> <listener-class> org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap </listener-class> </listener> <servlet> <servlet-name>resteasy-servlet</servlet-name> <servlet-class> org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher </servlet-class> </servlet> <servlet-mapping> <servlet-name>resteasy-servlet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app>
Crie uma classe que será o nosso service.
@Path("/crud") public class ServiceCrud { static List<String> pessoas = new ArrayList<String>(); }
A anotação @Path é o caminho de acesso para o nosso serviço. Exemplo: locahost:8080/nomeAplicacao/mapping.prefix/@Path. Irá ficar mais claro, quando fizermos uma chamada de um método. Adicionei também um ArrayList de pessoas que irá simular o nosso crud. 🙂
Antes de apresentar os métodos. Vamos entender a respeito de algumas anotações que serão adicionadas.
@POST – Utilizado para gravar alguma informação.
@PUT – Utilizado para editar alguma informação.
@DELETE – Utilizado para excluir alguma informação.
@GET – Utilizado para obter alguma informação.
Criando método inclusão (POST)
@POST @Path("/insert") @Produces(MediaType.TEXT_PLAIN + "; charset=UTF-8") public Response insert(String nome) { pessoas.add(nome); return Response.status(200).entity(pessoas).build(); }
Uma outra anotação importante é o @Produces que irá definir o tipo de saída para o response da chamada. Para esse caso foi definido a saída como texto. Contudo podemos ter vários tipos de saída, tais como: XML, JSON e etc. Além disso, foi definido o charset como UTF-8 para evitar problemas com caracteres especiais.
Para testarmos o serviço, irei utilizar o Postman. Adicionei 4 pessoas para nos ajudar nos testes: (Joselito, Fernanda, Fernanda, Carlos):
A URL é composta da seguinte forma:
locahost:8080/ – Caminho do servidor de aplicação;
rest-java/ – Nome do projeto;
rest/ – Prefixo adicionado no web.xml com o param resteasy.servlet.mapping.prefix;
crud/ – @Path Adicionado no topo da classe;
insert – @Path Adicionado no topo do método.
Criando o método de edição (PUT)
@PUT @Path("/edit") @Produces(MediaType.TEXT_PLAIN + "; charset=UTF-8") public Response edit(String objeto) { String array[] = objeto.split(";"); String nomeAntigo = array[0]; String nomeNovo = array[1]; for (int i = 0; i < pessoas.size(); i++) { if (pessoas.get(i).equals(nomeAntigo)) { pessoas.set(i, nomeNovo); } } return Response.status(200).entity(pessoas).build(); }
Vejamos a chamada.
Criando o método exclusão (DELETE)
@DELETE @Path("/delete") @Produces(MediaType.TEXT_PLAIN + "; charset=UTF-8") public Response delete(String nome) { for (int i = 0; i < pessoas.size(); i++) { if (pessoas.get(i).equals(nome)) { pessoas.remove(i); } } return Response.status(200).entity(pessoas).build(); }
Chamada:
Criando o método consultarTodos (GET)
@GET @Path("/select") @Produces(MediaType.TEXT_PLAIN + "; charset=UTF-8") public Response select() { return Response.status(200).entity(pessoas).build(); }
Chamada:
Criando o método consultarPorNomePathParam (GET)
Através do método get é possível passar parâmetros de entrada. Para isso, iremos apresentar dois exemplos.
@GET @Path("/select_nome_path/{nome}") public Response selectNomePath(@PathParam("nome") String nome) { for (int i = 0; i < pessoas.size(); i++) { if (pessoas.get(i).equals(nome)) { return Response.status(200).entity(pessoas.get(i)).build(); } } return Response.status(200).entity("Pessoa não encontrada").build(); }
Chamada:
Criando o método consultarPorNomeQueryParam (GET)
@GET @Path("/select_nome_query") public Response selectNomeQuery(@QueryParam("nome") String nome) { for (int i = 0; i < pessoas.size(); i++) { if (pessoas.get(i).equals(nome)) { return Response.status(200).entity(pessoas.get(i)).build(); } } return Response.status(200).entity("Pessoa não encontrada").build(); }
Chamada:
Existem outras anotações além da @PathParam e @QueryParam que não irei abordar nesse post. Recomendo a leitura desse post para quem quiser aprender um pouco mais.
Disponibilizei no GitHub o código fonte junto com a collection do Postman. Até a próxima! 😀