Criando uma aplicação com JSR-371(MVC 1.0)

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.

Logo_MVC_twitter_cmyk

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. Aqui vamos utilizar uma versão especifica do GlassFish que pode ser baixada no seguinte link : http://download.oracle.com/glassfish/5.0.1/nightly/latest-web.zip .   Feito isso, podemos da inicio.

Com o Eclipse aberto, vá File -> New – > Maven Project irá abrir a seguinte Janela :

maven

 clique em Next para ir para a seguinte tela :

maven2

    clique em Next, na próxima deixe preenchida da seguinte forma  e clique em Finish:

mvc1

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

mvc2

mvc3

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 :

mvc5

Clique em Finish e depois em OK.

Agora iremos configurar nosso pom.xml, com a seguinte configurações :

 Na pasta WEB-INF , configure o beans.xml do CDI da seguinte forma :

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 :

mvc6

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 {

	MongoClient conexao;
	MongoCollection 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 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 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 {

	void inserir(T entidade) throws MongoException;
	void alterar(T entidade) throws MongoException;
	void deletar(ObjectId _id) throws MongoQueryException;
	MongoCursor 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 org.mvcspec.ozark.engine.Viewable;
import javax.mvc.Controller;
import javax.mvc.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 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 :

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 :

e última tela que contem um formulário já preenchido com os valores do banco que podem ser alterados :

agora nossa pagina index.jsp contendo a url para chamar a tela mostrar.jsp e iniciar a aplicação.

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:

mongod

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 :

indexmvc

Clique no link  para ser levado a pagina que lista todos os dados, como na imagem :

telamvc

Clique no link Adicionar, irá ser levado para a tela de formulário:

telamvc2

Ao clicar em Cadastrar Dados, voltará para a tela de listagem dos dados :

listagem

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 :

alterar

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-spec

Ozark- RIOzark- RI

mvc-1-0-jsr-para-um-framework-mvc-action-based-na-java-ee-8

primeiros-passos-do-mvc-1-0

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

Anúncios

9 comentários sobre “Criando uma aplicação com JSR-371(MVC 1.0)

      1. 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.

        Curtido por 1 pessoa

  1. Fernando Franzini disse:

    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…

    Curtir

    1. Ola Derlon,

      por enquanto ela ainda vai ficar, pois ela é usando internamente na Ozark para seleção das View Templates. Mas não sei se vão remover. E bem possível de ninguém usa-la . por exemplo eu uso sempre o @View e/ou retorno via String .

      Curtir

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

w

Conectando a %s