JSR-371 ( MVC 1.0 ) – Com TomCat & TomEE

 

Logo_MVC_twitter_cmyk
Barista Duke – [DOAG](https://www.doag.org/de/home/)

Neste post veremos como podemos utilizar o MVC 1.0 juntamente com TomCat e TomEE a partir do modulo Ozark-RestEasy que foi comentado no post anterior .

TOMCAT

Iniciaremos pelo Tomcat pois é o que da mais trabalho durante as configurações.

Crie um projeto maven com as seguinte dependências :

feito isso, seguiremos para configuração dos arquivos beans.xml e context.xml :

dentro da pasta /src/main/webapp/WEB-INF crie um arquivo beans.xml com o seguinte conteudo :

agora na pasta src/main/resources/META-INF crie um arquivo context.xml com o seguinte conteudo :

Este arquivo é essencial para um correto funcionamento do CDI com o Tomcat, o mesmo é descrito aqui Weld Documentação .

Logo também devemos criar um aquivo web.xml na pasta src/main/webapp/WEB-INF com o seguinte conteúdo :

Com tudo pronto, podemos da inicio a um Hello Tomcat seguindo os post anteriores.

TOMEE

O TomEE utilizar a CXF como implementação do Jax-RS, porem a Ozark no momento não suporta por causa de bugs no CXF causando problemas com a utilização do Ozark.

Como alternativa, podemos utilizar o modulo Ozark-RestEasy para o seu funcionamento.

crie um projeto maven com o seguinte conteúdo :

Da mesma forma que vimos para o TomCat vamos precisar configurar nosso XML, mas ao invés de 3, serão apenas o beans.xml e o web.xml.

o conteúdo do web.xml na pasta src/main/webapp/WEB-INF com o seguinte conteúdo :


Com tudo pronto, podemos da inicio a um Hello TomEE seguindo os post anteriores.

Bem isso é tudo, aqui aprendemos  como fazer a api MVC 1.0 funcionar no TomCat & TomEE, espero que gostem, o código pode se encontrado aqui .

Atualmente a SPEC esta em Public Review e também estão movendo para Fundação Eclipse sobre o Projeto EE4J.

Sinta-se livre para se juntar à nossa lista de discussão e nos informar o que você acha. Você pode publicar suas opiniões na lista ou registrar um problema no rastreador de problemas.

REFERÊNCIAS

 

Anúncios

JSR-371 ( MVC 1.0 ) – Validação

Logo_MVC_www_cmyk
Barista Duke – [DOAG](https://www.doag.org/de/home/)

Muita coisa mudou na SPEC desde no meu último post  sobre o tema, se não sabe do que estou falando, veja o post anterior aqui  para montar o projeto para esse post.

Uma dessas mudanças é era que originalmente a mesma só funcionava com uma versão especifica do Glassfish/Payara  por causa do Jersey na qual a spec foi construída. Pois bem, atualmente esse problema foi resolvido e podemos utilizar também com Wildfly através de um módulo chamado Ozark-RestEasy e um chamado Ozark-Jersey para GlassFish/Payara, desta maneira não ficamos agarrados somente com Jersey .

Neste post veremos rapidamente como fazemos validações com a SPEC e vamos roda-la utilizando o Payara-Micro e Wildfly-Swarm ( farei um post sobre isso em breve) com seus respectivos módulos .

Maven Dependencies

crie um projeto maven e configure o pom.xml da seguinte forma :

<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.org.soujava.rio</groupId>
	<artifactId>MVC-Validacao</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>MVC-Validacao Maven Webapp</name>
	<url>http://maven.apache.org</url>

	<organization>
		<name>SouJava { Rio }</name>
		<url>http://soujava-rio.github.io</url>
	</organization>

	<properties>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<failOnMissingWebXml>false</failOnMissingWebXml>
		<version.payara>1.0.0</version.payara>
		<version.swarm>2017.12.1</version.swarm>
	</properties>

	<developers>
		<developer>
			<name>Daniel Dias</name>
			<email>daniel.dias@soujava.org.br</email>
			<organization>SouJava { Rio }</organization>
		</developer>
	</developers>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.wildfly.swarm</groupId>
				<artifactId>bom-all</artifactId>
				<version>${version.swarm}</version>
				<scope>import</scope>
				<type>pom</type>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<dependencies>
		<dependency>
			<groupId>javax.mvc</groupId>
			<artifactId>javax.mvc-api</artifactId>
			<version>1.0-pr</version>
		</dependency>

		<dependency>
			<groupId>org.mvc-spec.ozark</groupId>
			<artifactId>ozark-core</artifactId>
			<version>1.0.0-m03</version>
		</dependency>

		<dependency>
			<groupId>org.eclipse.microprofile</groupId>
			<artifactId>microprofile</artifactId>
			<version>1.2</version>
			<type>pom</type>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.16.14</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<artifactId>hibernate-validator</artifactId>
			<groupId>org.hibernate</groupId>
			<version>5.4.1.Final</version>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
	</dependencies>

	<build>
		<finalName>MVC-VALIDACAO</finalName>
	</build>

	<profiles>
		<profile>
			<id>payara</id>
			<build>
				<plugins>
					<plugin>
						<groupId>fish.payara.maven.plugins</groupId>
						<artifactId>payara-micro-maven-plugin</artifactId>
						<version>${version.payara}</version>
						<executions>
							<execution>
								<goals>
									<goal>bundle</goal>
									<goal>start</goal>
								</goals>
							</execution>
						</executions>
						<configuration>
							<useUberJar>true</useUberJar>
							<deployWar>false</deployWar>
							<daemon>false</daemon>
							<payaraVersion>5.Beta1</payaraVersion>
						</configuration>
					</plugin>
				</plugins>
			</build>
			<dependencies>
				<dependency>
					<groupId>org.mvc-spec.ozark</groupId>
					<artifactId>ozark-jersey</artifactId>
					<version>1.0.0-m03</version>
				</dependency>
			</dependencies>
		</profile>

		<profile>
			<id>wildfly</id>
			<build>
				<plugins>
					<plugin>
						<groupId>org.wildfly.swarm</groupId>
						<artifactId>wildfly-swarm-plugin</artifactId>
						<version>${version.swarm}</version>
						<executions>
							<execution>
								<goals>
									<goal>package</goal>
								</goals>
							</execution>
						</executions>
					</plugin>
				</plugins>
			</build>
			<dependencies>
				<dependency>
					<groupId>org.mvc-spec.ozark</groupId>
					<artifactId>ozark-resteasy</artifactId>
					<version>1.0.0-m03</version>
				</dependency>
			</dependencies>
		</profile>
	</profiles>
</project>

Criando as Classes

Vamos inicia pela a classe application.

Esta classe simplesmente inicia a nossa aplicação, para que funcione a validação corretamente  no Jersey devemos adicionar um pouco mais de código como pode ser visto abaixo :


@ApplicationPath("app")
public class APP extends Application {

	@Override
    public Map<String, Object> getProperties() {

		Map<String, Object> props = new HashMap<>();

        // https://github.com/jersey/jersey/issues/3659
        props.put("jersey.config.beanValidation.disable.validateOnExecutableCheck.server", true);

        return props;
    }
}
 

 

Na nossa classe modelo sera algo bem simples com dois atributos nome e e-mail juntamente com as anotações do Bean Validation/Hibernate Validation :

 


import javax.mvc.binding.MvcBinding;
import javax.validation.constraints.Size;
import javax.ws.rs.FormParam;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;

import lombok.Getter;

@Getter
public class JUG {

	@MvcBinding
	@NotEmpty
	@Size(min = 1, max = 20)
	@FormParam("nome")
	private String nome;

	@MvcBinding
	@Email
	@NotEmpty
	@FormParam("email")
	private String email;
} 

aqui a única novidade é a anotação @MvcBinding , que serve para habilitar as regras de vinculação específicas do MVC, para quando uma validação falhar não resulte em uma ConstraintViolationException. Em vez disto a correspondente ConstraintViolation é armazenada em uma instancia do BindingResult com escopo de solicitação que pode ser injetada no controlador.

Isso permite que o controlador manipule o erro ao invés de confiar em um mecanismo global de tratamento de erros, como um ExceptionMapper.

Vejamos como fica nosso controlador para o tratamento de erros de validação :


import java.util.stream.Collectors;

import javax.inject.Inject;
import javax.mvc.Models;
import javax.mvc.annotation.Controller;
import javax.mvc.annotation.View;
import javax.mvc.binding.BindingResult;
import javax.mvc.binding.ValidationError;
import javax.validation.Valid;
import javax.validation.executable.ExecutableType;
import javax.validation.executable.ValidateOnExecution;
import javax.ws.rs.BeanParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;

import br.org.soujava.rio.model.JUG;

@Controller
@Path("validacao")
public class ValidacaoController {

	@Inject
	private Models models;

	@Inject
	private BindingResult bindingResult;

	@POST
	@Path("validar")
	@ValidateOnExecution(type = ExecutableType.NONE)
	public String registrar(@Valid @BeanParam JUG jug) {
		if (bindingResult.isFailed()) {

			String erros = bindingResult.getAllValidationErrors()
					.stream()
					.map(ValidationError::getMessage)
					.collect(Collectors.joining("< br >"));

			models.put("erros", erros);
			return "form.jsp";
		}
		models.put("jug", jug);
		return "mensagem.jsp";
	}

	@GET
	@View("form.jsp")
	@Path("form")
	public void getForm() {
	}
}
 

Aqui precisamos injetar o nosso BindingResult e adicionar algumas configurações para que ocorra o tratamento de erros. Alem de injetar o BindingResult, precisamos também anotar nosso método com @ValidateOnExecution(type = ExecutableType.NONE) que de acordo com a SPEC , ela é necessária para garantir que o CDI e BV não abortem a invocação ao detectar uma violação. Assim, para garantir a semântica correta, a validação deve ser realizada pelo JAX-RS implementação antes do chamado método.

Para verificarmos os erros chamamos o método isFailed() que retorna TRUE se encontrar erros durante a validação.

Feito isso passamos para o para próxima instrução para pegarmos as mensagens de erros e exibir para usuário através da chamado getAllValidationErrors() que recuperar todos os erros de validação que ocorrer, fazemos um map para obter somente as mensagens de erros através da classe ValidationError do MVC , logo depois coletamos e juntamos com uma tag. Depois passo a minha variável para ser exibida na minha view através do Models que faz a ligação entre meu modelo e minha pagina .

Agora em nossa pagina JSP  fica da seguinte forma :


<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC-VALIDACAO</title>
</head>
<body>

	<c:if test="${erros != null}">
<div>
<div>

< p style="background-color: red;" > ${erros} < / p ></div>
</div>
</c:if>
<form action="validar" method="post">

		<label for="nome">Nome:</label> <input id="nome" type="text" name="nome"/>
		<label for="email">Email:</label> <input id="email" type="text" name="email"/>

		<input type="submit" value="Registrar" />
	</form>

</body>
</html>

Agora bastamos rodar nossa aplicação com os seguinte comandos :

Payara-Micro :

mvn clean -P payara payara-micro:bundle && mvn -P payara payara-micro:start

bastando acessar a URL que sera exibida no terminal pronto .

Wildfly-Swarm :

mvn clean package -P wildfly && cd target/ && java -jar *.jar

bastando acessar a URL http://localhost:8080

error
Tela com erro de Validação .

Bem isso é tudo, aqui aprendemos  como fazer validação utilizado a api MVC 1.0 , espero que gostem, o código pode se encontrado aqui e uma demo rodando no Heroku com Wildfly-Swarm .

Atualmente a SPEC esta em Public Review e também estão movendo para Fundação Eclipse sobre o Projeto EE4J.

Sinta-se livre para se juntar à nossa lista de discussão e nos informar o que você acha. Você pode publicar suas opiniões na lista ou registrar um problema no rastreador de problemas.

REFERÊNCIAS

 

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