UaiMockServer – Muitas novidades para ajudar ainda mais em seus testes

Olá, tudo bem?

A nova versão do uaiMockServer tem diversas novas funcionalidades que vão revolucionar os frameworks open source que fazem papel de mock HTTP.

A primeira grande novidade é justamente uma tela que permite a edição dos seus requests:

Index

Index

Agora não será mais necessário você editar seus requests através de um tedioso arquivo de configuração, utilize a ferramenta gráfica que fará isso de modo simples e prático. Basta acessar a tela de edição pela URL: http://localhost:1234/uaiGui/index

Outra novidade é justamente poder identificar o que está sendo enviado e recebido no request de um modo prático. Basta ir na aba “Log” e disparar o request:

Request Log

Request Log

Ao detalhar um request com sucesso você poderá ver:

Success Request

Success Request

Ao detalhar um requets com erro você verá como:

Error Detail 01

Error Detail 01

Um detalhe interessante é que será possível ver o Log do Servidor, esse log ajudará analisar o que aconteceu de errado no request:

Error Detail 02

Error Detail 02

E por último, mas não menos importante, agora é possível utilizar Runner em seus testes com JUnit. Veja o exemplo abaixo:

UaiMockServer JUnit Runner

UaiMockServer JUnit Runner

Desse modo você não precisa mais fazer o controle manual do seu servidor. Você também pode especificar qual o arquivo de configuração a ser utilizado:

UaiMockServer JUnit Runner Configuration

UaiMockServer JUnit Runner Configuration

E para você que usa o Spring, você também pode utilizar o Runner especializado para o Spring:

UaiMockServer JUnit SpringRunner Configuration

UaiMockServer JUnit SpringRunner Configuration

Uma última alteração que foi necessário é fazer a troca do tipo do arquivo de configuração, infelizmente não é mais possível usar o arquivo do tipo HCON como na primeira versão. Agora o arquivo deve ser no formato JSON. Peço desculpas ao incômodo que isso possa causar, mas foi uma mudança para melhor.

O arquivo de configuração está como abaixo:

New Configuration File as JSON

New Configuration File as JSON

Uma vantagem em ter o arquivo de configuração em formato JSON é justamente de qualquer editor de texto poder formatar o código.

Site do projeto: http://uaimockserver.com

Código fonte: https://github.com/uaihebert/uaiMockServer

Versão standalone e arquivo de configuração: https://sourceforge.net/projects/uaimockserver/

Import do Maven:

<dependency>
    <groupId>uaihebert.com</groupId>
    <artifactId>uaiMockServer</artifactId>
    <version>1.1.0</version>
    <scope>test</scope>
</dependency>

Espero que você goste das novidades.

Qualquer dúvida ou sugestão, poste como comentário abaixo.

o_

uaiMockServer – Crie um servidor Rest de teste com apenas uma linha de comando

Olá, tudo bem?

Sabe aquele momento em que você precisa chamar um serviço REST, mas esse serviço não está pronto ainda?

Imagine que você está desenvolvendo uma nova tela do APP que o serviço REST ainda não está pronto. Nesse caso você precisará ter um código falso em seu projeto, e esse código terá que ser substituído quando o serviço ficar pronto. Não importa se você trabalha com Java, .NET, PHP, Ruby, Python, etc.. Você terá que ter sempre o trabalho de primeiro criar o mock e depois criar a chamada real quando o serviço REST não estiver pronto.

Para testes unitários temos o mesmo problema, é comum termos uma classe com a implementação real e uma classe com um código falso. Na hora do teste é que a classe falsa é utilizada. O ruim dessa abordagem é que o código que executa a chamada nunca é testado.

Como podemos resolver esse problema? E o mais interessante: “existe uma solução que atenda delphi, .NET, PHP, Java, Android, IOS, WindowsPhone, etc?”

Apresento para vocês o mais novo produto que criei: “uaiMockServer

Com o uaiMockServer você poderá criar um servidor de teste utilizando o JAR e um arquivo de configuração. Com o uaiMockServer você poderá disparar os testes usando HTTP, mas com seus dados de testes.

Existem dois modos de utilizar o uaiMockServer: Standalone e com Testes Unitários.

Standalone

O modo standalone é quando você dispara o jar manualmente. Para executar o serviço manualmente basta fazer:

java -jar uaiMockServer-{VERSION}.Standalone.jar

Tudo o que você precisa agora é do arquivo de configuração que estará descrito mais abaixo.

No arquivo exemplo de configuração já vem mapeado um hello world apontando para a porta 1234. Se você estiver usando linux, execute o comando:

curl localhost:1234/uaiMockServer/

E você já verá o JSON retornado.

Testes Unitários

Primeiro passo é adicionar o projeto em seu pom:

<dependency>
   <groupId>uaihebert.com</groupId>
   <artifactId>uaiMockServer</artifactId>
   <version>1.0.1</version>
   <scope>test</scope>
</dependency>

Uma vez que a dependência já está em seu pom você pode criar um teste como o abaixo:

public class YourTest {
    private static UaiMockServer uaiMockServer;

    @BeforeClass
    public static void beforeClass() {
        uaiMockServer = UaiMockServer.start();
    }

    @AfterClass
    public static void afterClass() {
        uaiMockServer.shutdown();
    }

    @Test
    public void aTest() {
        final Customer customer = // invoke the URL
        assertTrue(customer != null);
    }
}

A chamada na URL tem que ser feita com algum framework de sua preferência. Eu coloco abaixo um exemplo feito utilizando RestEasy e o arquivo de configuração (mostrado mais abaixo):

@Test
public void isGetRootReturning200() {
    final String url = "http://localhost:1234/uaiMockServer/";

    Client client = ClientBuilder.newClient();
    Response response = client.target(url).request().get();

    assertEquals(200, response.getStatus());
}

A vantagem disso? Agora você não precisa mais de um código mock em seus testes. Você pode chamar diretamente do JUnit o servidor criado.

Configuração

Para rodar corretamente é necessário um arquivo de configuração. Um exemplo simples seria o arquivo abaixo:

com.uaihebert.uaimockserver {
	port = 1234
	host = localhost
	fileLog = false
	consoleLog = true
	context = /uaiMockServer
	defaultContentTypeResponse = "text/html;charset=UTF-8"
	routes = [
	    {
			request {
				path = "/"
				method = "GET"
			}
			response {
				contentType = "application/json;charset=UTF-8"
				statusCode = 200
				body = """{"mockBody":{"title":"Hello World"}}"""
			}
	    }
    ]
}

O arquivo tem que ter a extensão .config e não está no formato JSON, mas sim é um superset do JSON – HCON – utilizado para configurações (clique aqui para mais detalhes).

Com esse arquivo você pode configurar a porta a ser chamada, o host, header, queryparam e diversas outras funções que estão descritas na documentação do uaiMockServer.

Note que foi criado um request e response desse modo você pode simular toda chamada que você quiser.

Caso você rode a versão Standalone, esse arquivo deve ficar na mesma pasta que o jar. Você também pode passar o caminho completo assim:

java -jar uaiMockServer-{VERSION}.Standalone.jar CAMINHO_COMPLETO_DO_ARQUIVO

Caso você vá rodar o serviço em seus testes unitários (JUnit por exemplo), você deve colocar o arquivo na pasta “src/test/resources” do maven. Você também poderia passar o caminho completo do arquivo como:

uaiMockServer = UaiMockServer.start(CAMINHO_COMPLETO_DO_ARQUIVO);

É grátis?

Sim. Use a vontade.

O código fonte é aberto? Sim: https://github.com/uaihebert/uaiMockServer

A documentação está onde? http://uaimockserver.com

E para baixar o .config e o JAR Standalone? http://sourceforge.net/projects/uaimockserver/files/

Tem teste? Sim, Temos bastantes testes unitários e 100% de cobertura.

Performance desse trem é bom?

No próprio GIT tem um teste que dispara 300 requests e tem todas as resposta em menos de 2 segundos.

Agradecimentos Especiais

Aplicação Web Completa: Angular Twitter Bootstrap Spring MVC, Data e Security

Olá, tudo bem?

Hoje veremos como fazer uma aplicação Java web completa utilizando Spring, Angular, JQuery, Twitter Bootstrap, Tiles, Maven, Tomcat, JPA/Hibernate.

A aplicação feita neste post será a base do outro post que vou escrever, e por causa disso, será feito um passo a passo mostrando como preparar o ambiente para o projeto visto aqui hoje.  Apesar de utilizar o Linux como meu sistema operacional, pouco ou nada muda com relação às configurações de outros sistemas operacionais.

Diversas pessoas pediram por um post utilizando o Spring em uma aplicação completa, afinal todas as aplicações vistas aqui foram utilizando tecnologia JEE oficial (JSF, EJB, JPA). Neste post veremos uma aplicação utilizando o framework Spring com os seguintes módulos: Spring MVC, Spring Data e Spring Security. Veremos também como fazer internacionalização usando SpringMVC e aplicaremos templates com Tiles.

O banco de dados a ser utilizado é o Postgre, mas para utilizar o MySQL bastaria adicionar o jar o MySQL e alterar o arquivo de configuração ao banco de dados. Durante o post essas configurações que devem ser alteradas para se utilizar o MySQL serão destacadas.

É possível encontrar o código fonte na última página do post e, para agradar a todos, haverão diversos modos para baixar o código fonte. Nesse post veremos mais a parte do código Spring/JPA e alguns trechos das páginas JSP destacando o Angular e o Bootstrap, lembrando que o código completo das JSPs, classes e configurações é possível baixar na última página sem qualquer restrição. [=

O que veremos aqui:

Página 02: Montando ambiente
Página 03: Criando o projeto
Página 04: Entendendo o “pom.xml”, “log4j.xml” e o “context.xml”
Página 05: Criando os XMLS do Spring e da aplicação
Página 06: Tiles – Template de Páginas da Aplicação
Página 07: Criando o Modelo da Aplicação
Página 08: Utilizando o SpringData como Repositório (DAO); criar o Serviço dos Usuários
Página 09: Utilizando o SpringData como Repositório (DAO); criar o Serviço dos Contatos
Página 10: Criando os Controllers
Página 11: Utilizando Restful com SpringMVC
Página 12: Entendendo o Login, SpringMVC Interceptor e as Regras de Segurança
Página 13: Primeiro contato com Angular.js e o SpringMVC
Página 14: Utilizando o binding do Angular.js em um HTML table
Página 15: Internacionalização i18n com Spring
Página 16: Entendendo o papel Twitter Bottstrap
Página 17: Executando a aplicação

Sem mais delongas, vamos começar.

JSF Mini Livro – Dicas, conceitos e boas práticas

Olá, tudo bem?

Este post foi uma tentativa de escrever um artigo para uma revista de Java aqui do Brasil. Infelizmente não deu certo =(.Resolvi postar o artigo aqui! =D

Este artigo irá mostrar dicas, informações e soluções para os desenvolvedores que trabalham dia a dia com JSF 2.0. Serão apresentados conceitos e modos de usar o JSF para aqueles que trabalham com essa tecnologia ou tem interesse em conhecer mais sobre – estudantes, profissionais que trabalham com outros frameworks etc. Utilizar uma ferramenta sem entendê-la pode trazer problemas ao invés de soluções. É preciso entender o funcionamento do JSF, como ele trata cada ação do usuário e como é possível construir um código que otimize a utilização dessa ferramenta.

Serão apresentadas questões técnicas assim como: importar imagens/javascript para dentro das páginas, migrar um projeto JSF da versão 1.2 para a 2.0, utilizar o Ajax que é uma tecnologia de requisições assíncrona, entre outras; procurando abordar o lado teórico que freqüentemente é deixado de lado.

Com o JSF podemos enfrentar um dos maiores problemas da tecnologia web que é a dificuldade de reutilizar um código já escrito. O JSF nos permite reaproveitar páginas, códigos javascript, validações em código Java que são utilizados nas páginas. A reutilização dos códigos diminui o tempo gasto na manutenção das páginas da aplicação, reduz o impacto de mudanças, dentre outras vantagens.

O que será falado no post de hoje:

  • Página 02: Criando um projeto JSF
  • Página 03: Importando CSS/Imagens/JavaScript como biblioteca
  • Página 04: Reutilizando páginas com Facelets
  • Página 05: JSP x Facelets
  • Página 06: Escondendo os comentários da página xhtml
  • Página 07: Evite @SessionScoped. Veja todos os tipos de Escopos
  • Página 08: Evite colocar lógica nas páginas
  • Página 09: Utilize h:outputLink para navegação
  • Página 10: Ajax com JSF 2.0
  • Página 11: Facilitando o desenvolvimento com JSF 2.0
  • Página 12: Migrando do JSF 1.2 para o JSF 2.0
  • Página 13: Recebendo “null” da view
  • Página 14: Quando utilizar “action” ou “actionListener”
  • Página 15: Flash Scope
  • Página 16: Não misturar implementações do JSF
  • Página 17: Internacionalização como boa prática
  • Página 18: O que há de novo no JSF 2.2
Esse post também irá comemorar as mais de 200.000 visitas que o blog já recebeu nesses 2 anos de vida. [=

O “Pai do Java” usa Jelastic

Olá, tudo bem?

Hoje o post será diferente, será um informativo sobre essa ferramenta que tem crescido muito. O Jelastic tem por característica ser um servidor de servidores.

O material do post me foi enviado pelo Judah Johns da Jelastic.

Dr. James Gosling que é conhecido como um “Pai do Java” e tem uma longa carreira no ramo da tecnologia. Formado em no ano 1977 pela faculdade de Calgary, Canadá. Tornou PhD 1983 pela faculdade Carnegie-Mellon com a tese: “The Algebraic Manipulation of Constraints”. Durante muitos anos foi VP & Fellow da empresa Sun. Ele construiu sistemas para captação de informações de satélites, multiprocessadores para Unix, compiladores, sistemas de e-mails e e diversos editores de texto.

Enquanto funcionário da Sun foi líder no projeto NeWS. Ele desenvolveu o design original do Java e codificou o compilador e a máquina virtual. Ele tem contribuído para Real-Time Specification for Java e tem sido pesquisador nos laboratórios da Sun focado em ferramentas para desenvolvimento. Dr. James também trabalhou dentro da Sun em cargos de gerência de produtos para desenvolvedores e usuários. Continuou pouco tempo na Sun após a aquisição da Oracle, depois passou pelo Google e hoje é o líder de desenvolvimento na Liquid Robotics onde ele desenvolve sistemas para Wave Glider, um robô aquático em desenvolvimento.

Aplicação Web Completa Tomcat JSF Primefaces JPA Hibernate

Olá, tudo bem?

Nesse post comemorativo de 100.000 visitas será descrita uma aplicação web completa. O post de hoje utilizará as seguintes tecnologias: Tomcat7, JSF 2 (Facelets e Libraries) com Primefaces (utilizando AutoComplete), JPA / Hibernate (com relacionamento NxN), Login por Filter.

Caso você queira ver uma aplicação completa utilizando JSF + EJB + JPA + JAAS + JBoss 7 clique aqui.

Para o projeto de hoje você precisará dos artefatos abaixo (todos os JARs você encontra com o código fonte disponível na última página):

O banco utilizado foi o Postgres, mas você pode utilizar qualquer um. Basta alterar o driver e a url de conexão do arquivo persistence.xml.

Ao final desse post você irá encontrar o código fonte juntamente com as bibliotecas utilizadas no projeto.

O que será visto em cada página:

  • Página 02: Modelo mapeado com anotações JPA. Utilização do relacionamento NxN (@ManyToMany) , NamedQueries utilizando Join Fetch e Enum como atributo.
  • Página 03: DAO Genérico, controle de transação, utilizar métodos genéricos que preencham os parâmetros de uma query.
  • Página 04: Façades utilizando transações, utilizar método findReferenceOnly, cuidados ao utilizar o comando entityManager.merge().
  • Página 05: Filters.
  • Página 06: ManagedBeans. Injetar um ManagedBean dentro de outro, observações sobre @ViewScoped.
  • Página 07: JSFMessageUtil.
  • Página 08: Arquivos de configurações: log4j.properties, messages.properties.
  • Página 09: xhtml pages, Facelets.
  • Página 10: Primefaces AutoComplete, JSF Converter utilizando “forClass”.
  • Página 11: Facilitando o uso de CSS/javascript/imagens com JSF.
  • Página 12: Configurações “web.xml”.
  • Página 13: Práticas para um programa mais seguro.
  • Página 14: Executando a aplicação
  • Página 15: BUG_FIX

A aplicação de hoje terá um cadastro de pessoas e cachorros onde apenas o ADMIN poderá cadastrar os cachorros. Antes de executar o projeto crie o banco de dados: “JSFCrudDB”.

Paginação de Datatable Lazy com JSF (Primefaces)

Olá, tudo bem?

Vamos ver hoje como fazer uma paginação de um datatable JSF utilizando o modelo lazy em um managed bean de view scope. Quantos termos complicados em uma frase apenas.

Existem diversos frameworks JSF hoje no mercado que nos fornecem datatables prontos com paginação, ordenação e outras mais vantagens. Iremos utilizar como exemplo hoje o datatable do Primefaces.

É comum o datatable pegar todo a lista a ser exibida e alocar na sessão do usuário do servidor. Esse ato de alocar tudo na memória tem um impacto direto no desempenho do nosso servidor; cada usuário que exibir um datatable desse modo estará alocando mais espaço na memória do servidor.

Para ficar um pouco mais parecido com a vida real, no post de hoje será utilizado JPA e o HSQLDB como banco de dados, realizando as consultas com JPQL.

Ao final do post você irá encontrar o link para download do código fonte.

Iremos utilizar:

  • JSF 2.0 – Implementação JBoss 7
  • JBoss 7.1 – o tema proposto nesse post se aplica a qualquer servidor
  • Eclipse Indigo
  • JPA 2.0 – Implementação JBoss 7
  • HSQLDB (2.2.8) – O HSQL é um banco que roda na memória, apenas para facilitar nossa configuração.
  • Primefaces 3.2

Só para esclarecer, esse post não visa boas práticas ou colocar as devidas camadas de padrões de projetos. Pretendo apenas mostrar como aplicar paginação sem utilizar um managed bean de sessão.

Aplicação Web Completa JSF EJB JPA JAAS

Olá pessoal, bom dia.

Hoje vai ser o maior post que eu já fiz! Vamos ver uma aplicação completa. Ela será feita com tecnologias mais novas, mas darei dicas de como adaptar algumas partes para alguma tecnologia mais antiga assim que possível.

Ao final desse post você irá encontrar o código fonte para download. Pode utilizar como quiser. Basta ir para a última página e fazer o download. o/

Caso você baixe o código e não entenda alguma parte do código, eu expliquei tudo pelo decorrer desse post. Basta você ler a parte que te interessa e tirar suas dúvidas.

A aplicação será feita das seguintes tecnologias:

  • JSF 2.0 Mojarra – Utilizando Managed Beans de Request e Session.
  • Internacionalização das mensagens – Arquivo onde são definidas todas as mensagens do sistema, com isso você poderá facilmente traduzir seu programa.
  • Arquivo CSS padrão sendo utilizado como biblioteca.
  • EJB 3 – Utilizando DAO e Facades como @Stateless.
  • Generic DAO – Um DAO Genérico que terá as funções básicas de um cadastro facilitando assim a criação de entidades.
  • JPA 2 – Para mapear nossas classes no DB.
  • JAAS – Para controlar o login e nível de acesso do usuário.
  • MVC – Utilizarei o padrão MVC com pequenas alterações.
  • Postgres como banco de dados, mas vou mostrar como configurar para o MySQL também.

Não irei aplicar JUnit para teste dos métodos da View/Façade/Model, mas no link a seguir você poderá ver a técnica utilizar para usar o JUnit para testar os ManagedBeans do JSF: JUnit com HSQLDB, JPA e Hibernate.

Ferramentas para o post de hoje:

Este post será feito em várias páginas. Essa primeira página consta apenas os detalhes técnicos que serão utilizados na aplicação.

Não irei programar o meu modelo/DAO para interface, apenas para poupar espaço. Lembre de sempre programar para interface (Design Pattern – Strategy).

Antes de avançar, tenha certeza de que você instalou o JBoss Tools e depois o JBoss 7 (nessa ordem).

JSF Parametros por Get Request RESTFull

Olá tudo bem?

Como utilizar passagem de parâmetros via URL utilizando JSF? Creio que será o menor post aqui do blog, pois é muito simples.

Ao final do post você irá encontrar o link para download do código de hoje.

Os outros posts sobre JSF são: JSF Exemplos Simples com AjaxJSF Exibindo Objeto e Mensagens após Redirect, Validação de Login de Usuário com JSF e JAASJSF: Converter and Bean AutoCompleteJSF – Hello World, AutoComplete, Tratando Exceções em uma Aplicação Web, Autenticação de Usuários (Filter/Servlet), Criando um WebServer..

Veja como é simples o código para receber parâmetros via URL no JSF 2.0:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
	<f:metadata>
		<f:viewParam name="email" value="#{user.email}" />
		<f:viewParam name="name" value="#{user.name}" />
	</f:metadata>
</h:head>
<h:body>
	<h:form>
		Your email is: #{user.email} <br/>
		Your name is: #{user.name} <br/>
		Your name and email from MB: #{user.nameAndEmail} <br/>
	</h:form>
</h:body>
</html>
package demo;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

/**
 * Created by JBoss Tools
 */
@ManagedBean(name = "user")
@RequestScoped
public class User {

	private String email;
	private String name;

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getNameAndEmail(){
		return email + " " + name;
	}
}

A URL utilizada foi: http://localhost:8080/RequestParameter/values.xhtml?email=Read+Romans&name=Chapter10+Ver+09.

Como você pode ver a página espera dois parâmetros e existe um método que utiliza os dois parâmetros; seria o método em que você iria disparar a consulta no banco de dados ou qualquer outra ação necessária.

E como criar um link para o usuário navegar? Fácil, olhe e página abaixo:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>

</h:head>
<h:body>
	<h:form>
		01) A pre-formed link: <br/>
		<h:link outcome="values?email=Read Romans&amp;name=Chapter10 Ver 09" value="Let us go!" />
		<br/>
		<br/>
		02)Link with the f:param component<br/>
		<h:link outcome="values" value="Write all params and let us go!" >
			<f:param name="email" value="Read Romans" />
			<f:param name="name" value="Chapter10 Ver 09" />
		</h:link>
		<br/>
		<br/>
		03) <h:commandLink value="Redirect Me!" action="values?faces-redirect=true&amp;email=Read Romans&amp;name=Chapter10 Ver 09" />
	</h:form>
</h:body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
	<f:metadata>
		<f:viewParam name="email" value="#{user.email}" />
		<f:viewParam name="name" value="#{user.name}" />
	</f:metadata>
</h:head>
<h:body>
	<h:form>
		Your email is: #{user.email} <br/>
		Your name is: #{user.name} <br/>
		Your name and email from MB: #{user.nameAndEmail} <br/>

		04) <h:link outcome="values" value="Get everybody and leave this place" includeViewParams="true" />
	</h:form>
</h:body>
</html>

Vou comentar agora sobre cada abordagem utilizada na criação do link (de acordo com a numeração utilizada no código fonte “01,02…”):

  • 01)  Foi um link já formado onde todos os parâmetros estão escritos.
  • 02)  Utilizamos o componente “f:param” que acaba por deixar mais legível o código.
  • 03)  A navegação é feita através de um redirect e utilizando o commandLink. ATENÇÃO: até o dia de hoje, ainda não é possível utilizar o componente “f:param” junto com um redirect. Por isso que escrevi a URL toda de uma vez com o redirect no link. “<h:commandLink action=”values?faces-redirect=true.
  • 04) Com esse modo de link, com a opção (includeViewParams=”true”), você irá levar automaticamente todos os “f:viewParam” presentes na tela. Você nem irá precisar escrever os parâmetros progamaticamente. O JSF irá automaticamente pegar todos os parâmetros para você.

Você pode adicionar parâmetros de navegação após um redirect utilizando a faces-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
	<navigation-rule>
		<navigation-case>
			<from-outcome>redirectMe</from-outcome>
			<to-view-id>/myPage.xhtml</to-view-id>
			<redirect include-view-params="true">
				<view-param>
					<name>calculatedValue</name>
					<value>#{myBean.value}</value>
				</view-param>
			</redirect>
		</navigation-case>
	</navigation-rule>
</faces-config>

O código de hoje funciona com os componentes “<h:link />” e “<h:commandLink />” ambos podendo ser utilizados com ou sem a opção redirect.

Lembro também que seu link pode ser escrito em seu ManagedBean e seu valor acessado por #{meuMB.createTheURL} nos componentes link/commandLink.

Click aqui para fazer o download do código do post de hoje.

Espero que esse post possa te ajudar.

Qualquer dúvida/pergunta/colocação basta postar.

Até a próxima pessoal.

JSF Exemplos Simples com Ajax

Olá, tudo bem?

Hoje vamos exibir alguns simples modos de fazer chamadas Ajax utilizando JSF 2.0.

Para ver outros posts sobre Web Applications/JSF basta acessar os links a seguir: JSF Exibindo Objeto e Mensagens após Redirect, Validação de Login de Usuário com JSF e JAASJSF: Converter and Bean AutoCompleteJSF – Hello World, AutoComplete, Tratando Exceções em uma Aplicação Web, Autenticação de Usuários (Filter/Servlet), Criando um WebServer.

Ao final do post de hoje você verá o código para download. No post (Validação de Login de Usuário com JSF e JAAS) é exibido como instalar o JBoss 6 caso você queira executar o código do post de hoje. Você precisará instalar o JBoss Tools em seu Eclipse.

Veja a tela abaixo e seu respectivo código.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
	<h:form>
		Your Name: <h:inputText id="inputname" label="${msgs.prompt}" value="#{user.name}"/>
		<br />
		<h:commandButton action="#{user.sayHello}" value="Display my name here, now!"/>
		<br />
	</h:form>
</h:body>
</html>

Como exibir o nome digitado na mesma tela utilizando Ajax? Fácil, basta adicionar o comando “f:ajax” na linha e pronto. Veja a alteração e o resultado na página:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
	<h:form>
		Your Name: <h:inputText id="inputname" label="${msgs.prompt}" value="#{user.name}"/>
		<br />
		<h:commandButton action="#{user.sayHello}" value="Display my name here, now!">
			<f:ajax render="myName" execute="inputname" />
		</h:commandButton>
		<br />
		<br />
		<h:outputText id="myName" value="#{user.name}" />
	</h:form>
</h:body>
</html>

Viu como é simples? Passei apenas o valor que será levado,  para o ManagedBean, através do parâmetro “execute” e quem eu gostaria que o JSF atualizasse através do parâmetro “render”.

Repare que o nome digitado aparece no console também.

Esse exemplo serve para atualizar todos os tipos de componentes. Vamos para mais um?

Vamos fazer com que uma mensagem de erro seja exibida caso o nome preenchido tenha menos que 4 letras.

Veja o novo código da página e a mensagem exibida:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
	<h:form>
		<h:messages id="myMessage" globalOnly="true" showDetail="true"/>
		Your Name: <h:inputText id="inputname" label="${msgs.prompt}" value="#{user.name}"/>
		<br />
		<h:commandButton action="#{user.sayHello}" value="Display my name here, now!">
			<f:ajax render="myName myMessage" execute="inputname" />
		</h:commandButton>
		<br />
		<br />
		<h:outputText id="myName" value="#{user.name}" />
	</h:form>
</h:body>
</html>
package demo;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

/**
 * Created by JBoss Tools
 */
@ManagedBean(name = "user")
@RequestScoped
public class User {

	private String name;

	public String sayHello() {
		if (isNameIncorrect()) {
			FacesContext context = FacesContext.getCurrentInstance();
			context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Too small", "Can you write it a little bigger?"));
		}

		System.out.println(name);
		return null;
	}

	private boolean isNameIncorrect() {
		return "".equals(name.trim()) || name.length() < 3;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

Note no código que foi colocado um “h:messages” e ele tem seu ID utilizado pelo componente “f:ajax”.  Essa solução também funciona quando você tem um componente do tipo “h:message for=”YYY””.

Vamos trabalhar agora com comboboxes? Iremos exibir um combobox que contenha no máximo 4 itens quando temos um nome com menos de 6 caracteres ou uma lista com mais de 4 itens quando temos um nome com mais de 6 caracteres:

package demo;

import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UISelectItems;
import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;

/**
 * Created by JBoss Tools
 */
@ManagedBean(name = "user")
@RequestScoped
public class User {

	private String name;

	private List<String> cars;

	private String selectedCar;
	private HtmlSelectOneMenu htmlSelectCars;

	private static final String SELECT_A_CAR = "Select One Car";

	public User() {
		cars = new ArrayList<String>();
	}

	public String sayHello() {
		if (isNameInCorrect()) {
			FacesContext context = FacesContext.getCurrentInstance();
			context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Too small", "Can you write it a little bigger?"));
		}

		System.out.println(name);
		return null;
	}

	private boolean isNameInCorrect() {
		return name == null || "".equals(name.trim()) || name.length() < 3;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void editMyCarsList(AjaxBehaviorEvent event) {
		if (htmlSelectCars == null) {
			htmlSelectCars = new HtmlSelectOneMenu();
		}

		htmlSelectCars.getChildren().clear();

		UISelectItems items = new UISelectItems();
		items.setValue(getCars());
		htmlSelectCars.getChildren().add(items);
	}

	public List<String> getCars() {
		cars.clear();

		cars.add(SELECT_A_CAR);

		if (!isNameInCorrect() && name.length() >= 6) {
			cars.add("Ferrari");
			cars.add("Porch");
			cars.add("Beetle");
			cars.add("Opala");
			cars.add("Passat");
			cars.add("Vectra");
			cars.add("Chevet");
			cars.add("Corvet");
		} else {
			cars.add("Ferrari");
			cars.add("Porch");
			cars.add("Beetle");
			cars.add("Opala");
		}

		return cars;
	}

	public void setCars(List<String> cars) {
		this.cars = cars;
	}

	public String getSelectedCar() {
		return selectedCar;
	}

	public void setSelectedCar(String selectedCar) {
		this.selectedCar = selectedCar;
	}

	public HtmlSelectOneMenu getHtmlSelectCars() {
		editMyCarsList(null);

		return htmlSelectCars;
	}

	public void setHtmlSelectCars(HtmlSelectOneMenu htmlSelectCars) {
		this.htmlSelectCars = htmlSelectCars;
	}
}

Repare agora nosso código na página:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
	<h:form>
		<h:messages id="myMessage" globalOnly="true" showDetail="true" />
		Your Name: <h:inputText id="inputname" label="${msgs.prompt}" value="#{user.name}" />
		<br />
		<h:commandButton action="#{user.sayHello}" value="Display my name here, now!">
			<f:ajax render="myName myCars myMessage" execute="inputname" listener="#{user.editMyCarsList}" />
		</h:commandButton>
		<br />
		<br />
		<h:outputText id="myName" value="#{user.name}" />
		<br />
		<br />
		Choose your car: <h:selectOneMenu id="myCars" binding="#{user.htmlSelectCars}" value="#{user.selectedCar}" />
		<br />
		<br />
	</h:form>
</h:body>
</html>

Como você pode perceber no código acima, o combobox tem seu valor alterado de acordo com o nome digitado. Ao final do post, irei explicar por que utilizei o binding ao componente HtmlSelectOneMenu ao invés de passar uma lista (List<String>) diretamente.

Como último exemplo, vamos fazer com que tenha um combobox invisível que só apareça quando o usuário tiver selecionado algum carro.

Veja como ficar nosso ManagedBean:

package demo;

import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UISelectItems;
import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;

/**
 * Created by JBoss Tools
 */
@ManagedBean(name = "user")
@RequestScoped
public class User {

	private String name;

	private List<String> cars;
	private List<String> colors;

	private String selectedCar;
	private String selectedColor;
	private HtmlSelectOneMenu htmlSelectCars;

	private static final String SELECT_A_CAR = "Select One Car";

	public User() {
		cars = new ArrayList<String>();
		colors = new ArrayList<String>();

		colors.add("Red");
		colors.add("Blue");
		colors.add("Orange");
		colors.add("Pink --> O.o");
	}

	public String sayHello() {
		if (isNameInCorrect()) {
			FacesContext context = FacesContext.getCurrentInstance();
			context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Too small", "Can you write it a little bigger?"));
		}

		System.out.println(name);
		return null;
	}

	private boolean isNameInCorrect() {
		return name == null || "".equals(name.trim()) || name.length() < 3;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void editMyCarsList(AjaxBehaviorEvent event) {
		if (htmlSelectCars == null) {
			htmlSelectCars = new HtmlSelectOneMenu();
		}

		htmlSelectCars.getChildren().clear();

		UISelectItems items = new UISelectItems();
		items.setValue(getCars());
		htmlSelectCars.getChildren().add(items);
	}

	public List<String> getCars() {
		cars.clear();

		cars.add(SELECT_A_CAR);

		if (!isNameInCorrect() && name.length() >= 6) {
			cars.add("Ferrari");
			cars.add("Porch");
			cars.add("Beetle");
			cars.add("Opala");
			cars.add("Passat");
			cars.add("Vectra");
			cars.add("Chevet");
			cars.add("Corvet");
		} else {
			cars.add("Ferrari");
			cars.add("Porch");
			cars.add("Beetle");
			cars.add("Opala");
		}

		return cars;
	}

	public void setCars(List<String> cars) {
		this.cars = cars;
	}

	public String getSelectedCar() {
		return selectedCar;
	}

	public void setSelectedCar(String selectedCar) {
		this.selectedCar = selectedCar;
	}

	public List<String> getColors() {
		return colors;
	}

	public void setColors(List<String> colors) {
		this.colors = colors;
	}

	public boolean isColorsAlloweToDisplay() {
		if (isNameInCorrect()) {
			return false;
		}

		if (selectedCar == null || selectedCar.trim().equals("") || selectedCar.equals(SELECT_A_CAR)) {
			return false;
		}

		return true;
	}

	public String getSelectedColor() {
		return selectedColor;
	}

	public void setSelectedColor(String selectedColor) {
		this.selectedColor = selectedColor;
	}

	public HtmlSelectOneMenu getHtmlSelectCars() {
		editMyCarsList(null);

		return htmlSelectCars;
	}

	public void setHtmlSelectCars(HtmlSelectOneMenu htmlSelectCars) {
		this.htmlSelectCars = htmlSelectCars;
	}
}

Repare que foram alterações bem simples, onde adicionamos um List um método que irá dizer quando a lista deve ser exibida ou não.

Veja como ficou nossa página:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
	<h:form>
		<h:messages id="myMessage" globalOnly="true" showDetail="true" />
		Your Name: <h:inputText id="inputname" label="${msgs.prompt}" value="#{user.name}" />
		<br />
		<h:commandButton action="#{user.sayHello}" value="Display my name here, now!">
			<f:ajax render="myName myCars myMessage myColors" execute="inputname" listener="#{user.editMyCarsList}" />
		</h:commandButton>
		<br />
		<br />
		<h:outputText id="myName" value="#{user.name}" />
		<br />
		<br />
		Choose your car:
		<h:selectOneMenu id="myCars" binding="#{user.htmlSelectCars}" value="#{user.selectedCar}">
			<f:ajax render="myColors" execute="inputname myCars"/>
		</h:selectOneMenu>
		<br />
		<br />
		<h:panelGroup id="myColors">
			<h:selectOneMenu value="#{user.selectedColor}" rendered="#{user.colorsAlloweToDisplay}">
				<f:selectItems value="#{user.colors}" />
			</h:selectOneMenu>
		</h:panelGroup>
	</h:form>
	</h:body>
</html>

Agora farei diversas observações sobre o código e práticas adotadas:

  • HtmlSelectOneMenu – Eu utilizei o componente ao invés de uma simples lista por um pequeno detalhe. O JSF ainda não se dá bem na hora de construir os objetos na tela (DOM Tree). Com isso, se a primeira lista tinha 4 itens e depois, via ajax, você adiciona mais itens ele não irá reconhecer os itens mais novos. Com isso mesmo com uma lista contendo um novo valor o JSF não irá reconhecer, e você irá apenas poder utilizar os valores antigos. Você pode tentar com List<String> ao invés do component HtmlSelectOneMenu apenas e ver o que vai acontecer, fiquei umas 3~4 horas de pesquisa para achar uma solução.
  • HtmlSelectOneMenu dentro do “h:panelGroup” – Adicionei o selectOne dentro do panelGroup pois toda vez que um objeto não é exibido e você deseja exibi-lo é necessário atualizar todo seu container. Ou seja, se o segundo selectOne (cores) estivesse no mesmo “form”, você deveria utilizar seu “render” em todo o form.

Click Aqui para fazer o download do código do programa de hoje.

Espero que o post de hoje possa te ajuda.

Qualquer dúvida/pergunta/comentário poste abaixo.

Até a próxima