Neste artigo criaremos uma aplicação simples para demostrar o uso da API MVC 1.0 (JSR 371) do Java EE 8 juntamente com MongoDB.
Boa Leitura.
Introdução ao MVC 1.0
MVC é um padrão comum em frameworks web, onde este é usado predominantemente para criar aplicativos HTML. Frameworks web podem ser categorizados como Action-Based ou Component-Based. Em Action-Based, as solicitações HTTP são encaminhadas para controladores onde elas são transformadas em ações pelo código da aplicação. Em Component-Based, as solicitações HTTP são agrupadas e normalmente tratadas por framework de Componente, com pouca ou nenhuma interação do código da aplicação. Em outras palavras, um framework baseado em componentes, a maioria da sua lógica do controle é fornecida pelo framework em vez da aplicação.
Esta API se enquadra na categoria Action-Based, ela não se destina a substituição de frameworks baseado em componentes como a JSF, mas simplesmente uma alternativa para a construção de aplicações web para a plataforma Java EE.
Os Objetivos da API:
De acordo com a sua especificação está api propõe os seguintes objetivos:
- Aproveitar as tecnologias Java EE existentes.
- Integrar com CDI e Bean Validation
- Definir um núcleo solido para construir aplicações MVC sem a necessidade suportar todas as funcionalidade em sua primeira versão.
- Explora as camada em cima do JAX-RS com a finalidade de reutilizar suas camadas de Matching e binding.
- Fornece suporte interno para JSP e Facelets.
Não são Objetivos da API:
- Definir uma nova linguagem de visualização(template) e processador.
- Suporte a serviços REST não baseads em JAX-RS.
- Suporte a implementação autônoma do MVC executado fora do Java EE.
- Fornecer suporte interno para views que não fazem parte do Java EE.
Criando o Projeto
Antes de inciarmos a criação do projeto devemos fazer o download do servidor de Aplicação para que o mesmo funcione. Porém até o momento ela funciona com uma versão especifica do GlassFish que pode ser baixada no seguinte link : http://download.oracle.com/glassfish/4.1/nightly/glassfish-4.1-b17-09_15_2015.zip . Feito isso, podemos da inicio.
Com o Eclipse aberto, vá File -> New – > Maven Project irá abrir a seguinte Janela :
clique em Next para ir para a seguinte tela :
clique em Next, na próxima deixe preenchida da seguinte forma e clique em Finish:
com o projeto criado,vá em src/main/webapp, nela apague a pasta WEB-INF. Depois clique com o botão direito do mouse e vá em Properties, navegue até a opção Targeted Runtimes, marque a opção, que no caso vamos utilizar o GlassFish, depois clique em Uninstall Facets… :
ao chegar nesta tela desmaque Dynamic Web Module , altere Java 1.5 para 1.8,marque CDI,Glassfish Web Extensions e JAX-RS e clique em Finish. Abra novamente a mesma tela e maque Dynamic Web Module e mude de 2.3 para 3.1 e clique em Next para configura a proxima tela e a configure como abaixo :
Clique em Finish e depois em OK.
Agora iremos configurar nosso pom.xml, com a seguinte configurações :
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>br.com.danieldias</groupId> <artifactId>MVC1.0.Ozark</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>MVC1.0.Ozark Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> <!-- Mongo Driver --> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>org.glassfish.ozark</groupId> <artifactId>ozark</artifactId> <version>1.0.0-m02</version> <scope>compile</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-server</artifactId> <version>2.22</version> </dependency> </dependencies> <build> <finalName>MVC1.0.Ozark</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.5</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> </project>
Na pasta WEB-INF , configure o beans.xml do CDI da seguinte forma :
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all"> </beans>
Ainda dentro de WEB-INF também crie uma pasta chamada views.
Depois clique em cima do projeto e de “Alt +F5” para fazer update do maven :
Clique em OK e finalizamos a parte de criação projeto, podemos da inicio a codificação de nossas classes .
Criando a Constantes.java
Está classe é bem simples, ela irá somente conter valores constantes, que não serão modificadas. Isso para evitar ter muitas hardCode espalhado por todo o código, assim esse classe irá centralizar tudo de maneira organizada.
Crie uma classe chamada Constantes no package br.com.danieldias.commons, com o seguinte conteúdo :
package br.com.danieldias.commons; /** * @author daniel * github:Daniel-Dos * daniel.dias.analistati@gmail.com * twitter:@danieldiasjava */ public class Constantes { /*Nome o Banco e da Collection*/ public static final String BANCO_NOME = "danieldiasjava"; public static final String COLLECTION_NOME = "pessoas"; /*Nomes das Colunas para o MongoDB*/ public static final String NOME = "nome"; public static final String IDADE = "idade"; public static final String ENDERECO = "endereco"; public static final String ESTADO = "estado"; public static final String JUGS = "jugs"; public static final String DESCRICAO = "descricao"; public static final String ID = "_id"; }
Criando as Entidades
Crie as classes Pessoa.java e Endereco.java no package br.com.danieldias.model , com o seguinte conteúdo :
package br.com.danieldias.model; import javax.ws.rs.FormParam; import org.bson.types.ObjectId; /** * @author daniel * github:Daniel-Dos * daniel.dias.analistati@gmail.com * twitter:@danieldiasjava */ public class Pessoa { @FormParam("_id") private ObjectId _id; @FormParam("nome") private String nome; @FormParam("idade") private int idade; @FormParam("endereco") private Endereco endereco; @FormParam("jugs") private String jugs; @FormParam("descricao") private String descricao; public String getDescricao() { return descricao; } public void setDescricao(String descricao) { this.descricao = descricao; } public Pessoa() { } public Pessoa(String nome, Endereco endereco, String descricao,int idade, String jugs) { super(); this.nome = nome; this.endereco = endereco; this.descricao = descricao; this.idade = idade; this.jugs = jugs; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public Endereco getEndereco() { return endereco; } public void setEndereco(Endereco endereco) { this.endereco = endereco; } public ObjectId get_id() { return _id; } public int getIdade() { return idade; } public void setIdade(int idade) { this.idade = idade; } public String getJugs() { return jugs; } public void setJugs(String jugs) { this.jugs = jugs; } }
A anotação @FormParam, são utilizados para pegar os valores do form do html.
package br.com.danieldias.model; /** * @author daniel * github:Daniel-Dos * daniel.dias.analistati@gmail.com * twitter:@danieldiasjava */ public class Endereco { private String estado; public String getEstado() { return estado; } public void setEstado(String estado) { this.estado = estado; } public Endereco() { } public Endereco(String estado) { super(); this.estado = estado; } }
Criando o Repositorio
Agora criaremos uma Inteface chamada MongoDAO ,uma classe chamada PessoaDAO e uma classe que ira criar a fabrica de conexão chamada MongoDBFactory no package br.com.danieldias.persistencia, com os seguintes conteúdos:
package br.com.danieldias.persistencia; import com.mongodb.MongoClient; /** * @author daniel * github:Daniel-Dos * daniel.dias.analistati@gmail.com * twitter:@danieldiasjava */ public class MongoDBFactory { public static MongoClient createConnection() { MongoClient conexao = null; if(conexao == null) { conexao = new MongoClient(); } return conexao; } }
A classe PessoaDAO é onde fica todas as operações de CRUD para o MongoDB, nada muito fora do comum, tudo muito simples e fácil compreensão. Repare que estamos usando a classe Constantes aqui no lugar de String para facilitar o entendimento e deixar o código mas limpo.
package br.com.danieldias.persistencia; import static com.mongodb.client.model.Filters.eq; import java.util.ArrayList; import java.util.List; import org.bson.Document; import org.bson.types.ObjectId; import com.mongodb.MongoClient; import com.mongodb.MongoCursorNotFoundException; import com.mongodb.MongoException; import com.mongodb.MongoQueryException; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCursor; import br.com.danieldias.commons.Constantes; import br.com.danieldias.model.Pessoa; /** * @author daniel * github:Daniel-Dos * daniel.dias.analistati@gmail.com * twitter:@danieldiasjava */ public class PessoaDao implements MongoDAO<Pessoa> { MongoClient conexao; MongoCollection<Document> collectionPessoas; public PessoaDao() { conexao = MongoDBFactory.createConnection(); collectionPessoas = conexao.getDatabase(Constantes.BANCO_NOME) .getCollection(Constantes.COLLECTION_NOME); } @Override public void inserir(Pessoa entidade) throws MongoException { List<Document> jugs = new ArrayList<>(); jugs.add(new Document(Constantes.NOME,entidade.getJugs()) .append(Constantes.DESCRICAO, entidade.getDescricao())); collectionPessoas.insertOne(new Document(Constantes.NOME,entidade.getNome()) .append(Constantes.ENDERECO, new Document(Constantes.ESTADO,entidade.getEndereco().getEstado()) ) .append(Constantes.IDADE,entidade.getIdade()) .append(Constantes.JUGS, jugs) ); } @Override public void alterar(Pessoa entidade) throws MongoException { collectionPessoas.updateOne(porId(entidade.get_id()), new Document("$set", new Document(Constantes.IDADE,entidade.getIdade()) .append(Constantes.NOME, entidade.getNome()) .append(Constantes.ENDERECO, new Document(Constantes.ESTADO,entidade.getEndereco().getEstado())) ) ); } @Override public void deletar(ObjectId _id) throws MongoQueryException { collectionPessoas.findOneAndDelete(porId(_id)); } @Override public MongoCursor<Document> listarTodos() throws MongoCursorNotFoundException, MongoQueryException { return collectionPessoas.find().iterator(); } @Override public Document porId(ObjectId _id) throws MongoQueryException { return collectionPessoas.find(eq(Constantes.ID,_id)).first(); } }
Agora nossa interface generica:
package br.com.danieldias.persistencia; import org.bson.Document; import org.bson.types.ObjectId; import com.mongodb.MongoCursorNotFoundException; import com.mongodb.MongoException; import com.mongodb.MongoQueryException; import com.mongodb.client.MongoCursor; /** * @author daniel * github:Daniel-Dos * daniel.dias.analistati@gmail.com * twitter:@danieldiasjava */ public interface MongoDAO<T> { void inserir(T entidade) throws MongoException; void alterar(T entidade) throws MongoException; void deletar(ObjectId _id) throws MongoQueryException; MongoCursor<Document> listarTodos() throws MongoCursorNotFoundException,MongoQueryException; Document porId(ObjectId _id) throws MongoQueryException; }
Criando os Controles
Entramos na parte principal, aqui veremos com a api funciona.
Crie uma nova classe chamada PessoaController no package br.com.danieldias.controller, com o seguinte conteúdo :
package br.com.danieldias.controller; import javax.inject.Inject; import javax.mvc.Models; import javax.mvc.Viewable; import javax.mvc.annotation.Controller; import javax.mvc.annotation.View; import javax.ws.rs.BeanParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import org.bson.types.ObjectId; import br.com.danieldias.model.Pessoa; import br.com.danieldias.persistencia.MongoDAO; /** * @author daniel * github:Daniel-Dos * daniel.dias.analistati@gmail.com * twitter:@danieldiasjava */ @Controller @Path("mvc") public class PessoaController { @Inject Models models; @Inject MongoDAO<Pessoa> pessoaDao; @GET @Path("novo") public Viewable novo() { return new Viewable("inserir.jsp"); } @GET @Path("mostrar") @View("mostrar.jsp") public void listar() { this.models.put("listar", pessoaDao.listarTodos()); } @POST @Path("add") public String adicionar(@BeanParam Pessoa pessoa) { pessoaDao.inserir(pessoa); return "redirect:mvc/mostrar"; } @POST @Path("update") public String atualizar(@BeanParam Pessoa pessoa) { pessoaDao.alterar(pessoa); return "redirect:mvc/mostrar"; } @GET @Path("atualizar/{_id}") public Viewable update(@PathParam("_id") ObjectId _id) { this.models.put("update",pessoaDao.porId(_id)); return new Viewable("alterar.jsp",models); } @GET @Path("remover/{_id}") public String deletar(@PathParam("_id") ObjectId _id) { pessoaDao.deletar(_id); return "redirect:mvc/mostrar"; } }
O código é semelhante ao que usamos no Spring. Então nessa parte fica bem tranquila de aprender quando a API for lançada oficialmente, é até la vai haver muitas mudanças e melhoramentos.
O @Controller, quando aplicada a uma classe, todos os métodos nele são considerados como controladores. Ao usar a anotação @Controller em um subconjunto de métodos define uma classe hibrida em que certos métodos são controladores e outros são métodos tradicionais do JAX-RS.
O @Path é o endereço que iremos acessar determinada ação para o controlador e acessar outros métodos por outras endereços também, isso é semelhante ao @RequestMapping() do spring.
A class Viewable encapsula informações sobre uma visualização, bem como, opcionalmente, informações sobre como ele deve ser processado. Mais precisamente, uma instância Viewable pode incluir referências a Modelos e Objetos ViewEngine. Comparada ao Spring ela seria como ModelAndView.
Models é a interface que define um mapa entre nomes e objetos. O suporte para a interface Models é obrigatória para todos os view engines, porém podemos usar OPCIONALMENTE o @Named do CDI que é fortemente recomendado para aproveitar a integração CDI e EL existente na plataforma.
Os métodos do controlador que retornam um tipo não-vazio(void) também podem ser decorados com @View como uma forma de especificar um padrão para o controlador. A visualização padrão deve ser usada somente quando tal controlador não vazio retorna um valor nulo.
A anotação @BeanParam é algo novo adicionado na especificação JAX-RS 2.0. Ele permite que você injete uma classe específica de aplicativo cujos métodos de propriedade ou campos são anotados com qualquer um dos parâmetros de injeção, como foi utilizada o @FormParam.
@PathParam permite que você injete o valor de parâmetros de caminho URI nomeados que foram definidos em expressões @Path.
Criando as Views
Agora daremos inicio a criação de 4 páginas para nossa aplicação que são : alterar.jsp, inserir.jsp ,mostrar.jsp que devem ser criada na pasta views que fica dentro de WEB-INF, já a index.jsp deve ser criada em na pasta webapp.
Iniciaremos pela a página mostrar.jsp, onde a mesma terá uma tabela onde os dados serão apresentados, 3 links um para chamar a paǵina alterar.jsp passando um parâmetro que é seu id e um que irá chamar no controle o deletar com parâmetro id e um para estarmos adicionando os dados no formulario inserir.jsp :
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Mostrar</title> </head> <body> <h1 align="center">Listagem dos Dados</h1> <a href="novo">Adicionar</a> <table align="center" border="4"> <tr bgcolor="gray"> <th>ID</th> <th>Nome</th> <th>Idade</th> <th>Estado</th> <th>JUGS</th> <th>Descrição</th> <th>Editar</th> <th>Deletar</th> </tr> <c:forEach items="${listar}" var="pessoas"> <tr> <td>${pessoas._id}</td> <td>${pessoas.nome}</td> <td>${pessoas.idade}</td> <td>${pessoas.endereco.estado}</td> <td>${pessoas.jugs.get(0).nome}</td> <td> <textarea rows="10" cols="60" name="descricao" disabled="disabled"> ${pessoas.jugs.get(0).descricao} </textarea></td> <td><a href="atualizar/${pessoas._id }">Alterar</a></td> <td><a href="remover/${pessoas._id}">Excluir</a></td> </tr> </c:forEach></table> </body> </html>
Algo importante nesta tela. Aqui os atributos passado devem SER o mesmo que estão no mongoDB, ou seja as colunas tem que ter os mesmo nome. A mesma coisa nesse techo : ${pessoas.jugs.get(0).nome}, aqui estou retornado o primeiro posição no array, se quisermos chamar outra posição fazemos assim : ${pessoas.jugs.get(1).lideres}.
A proxima tela é um formulario bem simples com o seguinte conteudo :
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Inserir</title> </head> <body> <div align="center"> <form action="add" method="post"> <fieldset style="width: 400px"> <legend>Dados</legend> Nome: <input type="text" name="nome" /> Idade: <input type="number" name="idade"/> Estado: <input type="text" name="endereco"/> JUGS:<input type="radio" name="jugs" value="SouJava"/>SouJava <input type="radio" name="jugs" value="RioJug"/>RioJug <input type="radio" name="jugs" value="SouJava Campinas"/>SouJava Campinas <textarea rows="10" cols="30" name="descricao">Descrição</textarea> <input type="submit" value="Cadastrar Dados."/></fieldset> </form></div> </body> </html>
e última tela que contem um formulário já preenchido com os valores do banco que podem ser alterados :
<%@page contentType="text/html" language="java" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Atualizar Dados</title> </head> <body> <div align="center"> <form action="../update" method="post"> <fieldset style="width: 400px"> <legend>Alteração de Dados</legend> <input type="text" name="_id" value="${update._id }" hidden="true"> Nome:<input type="text" name="nome" value="${update.nome }"> Idade: <input type="number" name="idade" value="${update.idade }"/> Cidade<input type="text" name="endereco" value="${update.endereco.estado}"> <textarea rows="10" cols="30" name="descricao" disabled="disabled">${update.jugs.get(0).descricao}</textarea> <input type="submit" value="Atualizar"></fieldset> </form></div> </body> </html>
agora nossa pagina index.jsp contendo a url para chamar a tela mostrar.jsp e iniciar a aplicação.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Index MVC</title> </head> <body> <h1 align="center">Demo JSR 371 - MVC 1.0</h1> <div align="center"> <ul type="none"> <li ><a href="app/mvc/mostrar">Listar Dados</a></li> </ul> </div> </body> </html>
por fim iniciar a aplicação devemos criar uma classe que extenda a javax.ws.rs.core.Application e anota-la com @ApplicationPath, essa classe deve ser criada no package br.com.danieldias.application com o seguinte conteúdo :
package br.com.danieldias.application; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; /** * @author daniel * github:Daniel-Dos * daniel.dias.analistati@gmail.com * twitter:@danieldiasjava */ @ApplicationPath("app") public class MVCApplication extends Application { }
Rodando a Aplicação
Com tudo pronto, podemos testar a nossa aplicação:
Primeiramente inicie o MongoDB através do prompt/terminal com o seguinte comando : mongod, como na imagem:
Depois rode a aplicação no glassfish , com o botão direito do mouse clique no seu projeto e vá em Run As -> Run on Server, ao inicia a aplicação a página principal será carregada com abaixo :
Clique no link para ser levado a pagina que lista todos os dados, como na imagem :
Clique no link Adicionar, irá ser levado para a tela de formulário:
Ao clicar em Cadastrar Dados, voltará para a tela de listagem dos dados :
Agora clicando em Excluir irá deletar a informação através do ID que foi passado por parâmetro. Em Alterar será levado a tela de alteração de dados e retornara para tela de listagem :
Bem isso é tudo, aqui aprendemos a como fazer uma aplicação utilizado a api MVC1.0 do JEE 8 com MongoDB . O projeto pode ser baixado no meu GitHub.
Outros exemplos da API pode ser encontrados aqui : https://github.com/spericas/ozark/tree/master/test
Para saber mais sobre a API visite os seguintes sites :
mvc-1-0-jsr-para-um-framework-mvc-action-based-na-java-ee-8
REFERÊNCIAS
https://dennis-xlc.gitbooks.io/restful-java-with-jax-rs-2-0-2rd-edition/content/en/index.html
https://jcp.org/en/jsr/detail?id=371
http://download.oracle.com/otn-pub/jcp/mvc-1-edr2-spec/JSR_371-EDR-Spec-MVC-1_0-10_2_15.pdf
Excelente!
Adeus springMVC…..ja ja estaremos com esse produto em produção!
CurtirCurtido por 1 pessoa
Concordo com você, achei a JSR bem legal,porem precisar ser mais desenvolvida. Agora o Spring MVC ganhou um concorrente de peso.
CurtirCurtir
Spring MVC é legal…mas é muito proprietário meu..não da pra usar….
Ja ta certo que sai na JEE8?
CurtirCurtido por 1 pessoa
De acordo com o resultado deste site : https://blogs.oracle.com/theaquarium/entry/java_ee_8_community_survey2 , a JSR 371 (Sai). Recentemente foi divulgado a transferência da JSR para a comunidade e para um novo Spec Lead será selecionado após a votação que termina dia 30/01, a galera do SouJava votou sim para o indicado Ivar Grimstad para assumir a Spec. Ainda de acordo com o site “Investigando uma possível transferência de MVC para outro membro da comunidade ou organização, a fim de completar JSR 371 como um componente autônomo.”
Mas eu espero que saia no JEE 8, pois esperar por uma outra versão do JEE vai demorar. Também acho o Spring legal, mas ficamos preso nele, caso mude algo teremos que modificar a aplicação. Mas tendo uma solução desta dentro do JEE, a adoção deve ser mais forte, ainda mais se a api acrescentar algo a mais, que seja atrativo para todos.
CurtirCurtido por 1 pessoa
Muito bom….vamos aguardar…
CurtirCurtido por 1 pessoa
sim, o jeito é aguardar para novas noticias.
CurtirCurtir
Ola Daniel…Sou responsavel pela empresa FORJ – https://for-j.myedools.com/ e estou a procura de um profissional java com interesse e tempo disponível para ser instrutor de cursos ead. Tenha acompanhado seus post e seus perfil e acredito que seja possível. Vc tem interesse? Me add no whatszapp e agente se fala 43 984074007. A paz…
CurtirCurtir