Criando e consumindo um serviço rest com java

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):

java-insert2

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.

edit-java

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:

delete-java

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:

consultar-todos

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:

consultarPorNomePath

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:

consultarPorNomeQueryParam

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! 😀

Deixe uma resposta