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 :


<!-- Get the API JARs for Java EE 7 -->
<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>7.0</version>
</dependency>

<!-- Weld  -->
<dependency>
    <groupId>org.jboss.weld.servlet</groupId>
    <artifactId>weld-servlet-core</artifactId>
    <version>2.4.3.Final</version>
</dependency>

<!-- RESTEasy -->
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-cdi</artifactId>
    <version>3.1.4.Final</version>
</dependency>
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-servlet-initializer</artifactId>
    <version> 3.1.4.Final</version>
</dependency>

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

<!-- MVC + Ozark for RESTEasy-->
<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-resteasy</artifactId>
    <version>1.0.0-m03</version>
</dependency>
 

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 :

 <?xml version="1.0"?>
<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
"version="1.1" bean-discovery-mode="all">

</beans>
 

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

 <?xml version="1.0" encoding="UTF-8"?>
<Context>

   <Resource name="BeanManager" auth="Container"
type="javax.enterprise.inject.spi.BeanManager"
factory="org.jboss.weld.resources.ManagerObjectFactory"/>

</Context>
 

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 :

 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd" version="3.1">

	<listener>
   	<listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>

  <resource-env-ref>
    <resource-env-ref-name>BeanManager</resource-env-ref-name>
    <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
  </resource-env-ref>

  <!--http://docs.jboss.org/resteasy/docs/3.1.4.Final/userguide/html_single/index.html#d4e143 -->
  <context-param>
    <param-name>resteasy.injector.factory</param-name>
    <param-value>org.jboss.resteasy.cdi.CdiInjectorFactory</param-value>
  </context-param>

</web-app>
 

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 :

<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-resteasy</artifactId>
    <version>1.0.0-m03</version>
</dependency>

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-cdi</artifactId>
    <version>3.1.4.Final</version>
</dependency>

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-servlet-initializer</artifactId>
    <version>3.1.4.Final</version>
</dependency>

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>8.0</version>
    <scope>provided</scope>
</dependency>
 

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 :

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<display-name>tomee</display-name>
  <context-param>
	<param-name>resteasy.injector.factory</param-name>
	<param-value>org.jboss.resteasy.cdi.CdiInjectorFactory</param-value>
	</context-param>
</web-app>

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