Skip to content
llins edited this page Oct 3, 2014 · 54 revisions

Table of Contents

Faces

O módulo Faces representa a camada de apresentação, com a definição de que a tecnologia JSF deverá ser utilizada.

Neste módulo são utilizadas as tecnologias:

Controladoras

Suporte

Para facilitar o desenvolvimento das controladoras, foi desenvolvida a classe abstrata Controller, que possui uma série de métodos facilitadores.

Para utilizá-la basta que sua controladora estenda a classe Controller:

public class ListarPessoasController extends Controller

Ao estender a classe Controller sua controladora poderá usufruir de métodos facilitadores como:

Método invocado quando uma view é iniciada (sobrescreva!)
/**
 * Acao invocada sempre que a tela for iniciada.
 * Retorne nulo para seguir para a tela ou retorne uma viewId para redirecionar para outra tela
 * @return
 */
@RequestAction
@Deferred
@IgnorePostback
public String requestAction()
Métodos para serem utilizados nas views
/**
 * Util para saber se a controladora ja foi inicializada. 
 * Voce devera informar a inicializacao manualmente
 * @return
 */
public boolean isInitialized()

/**
 * Comparacao de strings com ignore case, util para dataTables com sort
 * @param obj1
 * @param obj2
 * @return
 */
public int sortIgnoreCase(Object obj1, Object obj2)

/**
 * Filtro de dados ignorando o caso, util para dataTables
 * @param value
 * @param filter
 * @param locale
 * @return
 */
public boolean filterIgnoreCase(Object value, Object filter, Locale locale)

/**
 * Metodo para ser utilizado em acoes de cancelamento que exigem a limpeza de um form.
 * Realiza, assim, a limpeza completa na arvore de componentes do JSF, do form que o botao se encontra.
 * @param event
 */
public void resetForm(ActionEvent event)
Métodos auxiliares para serem utilizados na controladora
/**
 * Retorna a referencia do FacesContext.
 * @return FacesContext
 */
protected FacesContext getContext()

/**
 * Retorna a referencia do FacesContext.
 * @return ExternalContext
 */
protected ExternalContext getExternalContext()

/**
 * Retorna a referencia para o HttpServletResponse atual.
 * @return HttpServletResponse
 */
protected HttpServletResponse getResponse()

/**
 * Retorna a referencia para o HttpServletRequest atual.
 * @return HttpServletRequest
 */
protected HttpServletRequest getRequest()

/**
 * Retorna a instancia atual do contexto ServletContext.
 * @return ServletContext
 */
protected ServletContext getServletContext()

/**
 * Retorna um parametro do Request HTTP (HttpServletRequest) sob a chave 'name'.
 * @param name - chave do parametro no Request HTTP
 * @return String - parametro do Request HTTP sob a chave 'name'
 */
protected String getParameter(String name)

/**
 * Retorna a referencia para o HttpSession atual.
 * @return HttpSession
 */
protected HttpSession getSession()

/**
 * Retorna o contexto de Flash
 * @return Flash
 */
protected Flash getFlash()

/**
 * Adiciona uma mensagem no facesMessages com severidade info.
 * @param msg
 * @param params
 */
protected void addMsg(String msg, Object ... params)

/**
 * Adiciona uma mensagem no facesMessages com severidade INFO, para o componente 
 * especificado
 * @param compoenentId
 * @param msg
 * @param params
 */
protected void addMsgToComponent(String componenteId, String msg, Object... params)

/**
 * Adiciona uma mensagem no facesMessages com severidade warn.
 * @param msg
 * @param params
 */
protected void addMsgWarn(String msg, Object... params)

/**
 * Adiciona uma mensagem no facesMessages com severidade WARN, para o componente 
 * especificado.
 * @param compoenentId
 * @param msg
 * @param params
 */
protected void addMsgWarnToComponent(String componenteId, String msg, Object... params)

/**
 * Adiciona uma mensagem no facesMessages com severidade error.
 * @param msg
 * @param params
 */
protected void addMsgErro(String msg, Object... params)

/**
 * Adiciona uma mensagem do bundle no facesMessages com severidade error, para o componente 
 * especificado.
 * @param compoenentId
 * @param msg
 * @param params
 */
protected void addMsgErroToComponent(String componenteId, String msg, Object... params)

/**
 * Lanca erro de validacao com a mensagem do bundle. 
 * @param key
 * @throws ValidatorException
 */
protected void throwValidationException(String key) throws ValidatorException

/**
 * Retorna a mensagem do arquivo properties default ("messages") formatada com os parametros passados.
 * 
 * @param key
 * @param params
 * @return mensagem formatada
 */
protected String getMessageFromDefaultBundle(String key, Object ... params)

/**
 * Retorna a mensagem do arquivo properties, que possui o nome passado como argumento, formatada com os parametros passados.
 * 
 * @param bundleName
 * @param key
 * @param params
 * @return mensagem formatada
 */
protected String getMessageFromBundle(String bundleName, String key, Object ... params)

/**
 * Metodo para limpar o componente, na arvore jsf, cujo id informado. 
 * @param componentClientId
 */
protected void resetComponent(String componentClientId)

Esteriótipos

Na versão atual do CDI e do JSF há o problema de que o escopo de View não é suportado pelo CDI. Para utilizar o escopo de View a sua controladora deverá ser uma ManageBean e não um bean gerenciado pelo CDI. O problema é que perde-se uma série de vantagens providas pelo CDI, como, por exemplo, interceptadores.

A arquitetura Suri-CDI corrige o problema (fonte DeltaSpike)! Logo, é possível criar a sua controladora da seguinte forma:

@Named
@ViewScoped
public class ListarPessoasController extends Controller

Mas para facilitar um pouco a vida, provemos os seguintes esteriótipos:

@ApplicationController
É o mesmo que: @Named + @ApplicationScoped
@SessionController
É o mesmo que: @Named + @SessionScoped
@ViewController
É o mesmo que: @Named + @ViewScoped
@RequestController
É o mesmo que: @Named + @RequestScoped


Desta forma, sua controladora pode ser criada da seguinte forma:

@ViewController
public class ListarPessoasController extends Controller

Interceptadores

@BusinessMessages
Este interceptador é responsável por capturar as BusinessException e transformá-las em mensagens de erro do JSF. Ou seja, ao lançar uma BusinessException na camada de Negócio, não é necessário que na controladora tenha o tratamento da exceção, pois será realizado automaticamente por este interceptador.


Exemplo:

@ViewController
@BusinessMessages
public class ManterPessoaController
A classe suporte Controller já possui essa anotação, logo todas as controladoras que estendam de Controller já terão o interceptor ativado, não sendo necessário adicionar a anotação em sua controladora.

Rewrite

Vemos no framework Rewrite um potencial e facilidades que consideramos essenciais para o desenvolvimento de qualquer aplicação web. Hoje em dia é muito comum o uso de urls amigáveis devido a série de vantagens e melhor usabilidade para o usuário.

Request Action
Para facilitar a utilização do framework, implementamos na classe Controller o método requestAction, que já possui as anotações necessárias para chamada quando uma view for iniciada. Além disso, possui as anotações para correta integração com os escopos do bean. Para utilizar o método basta sobrescrevê-lo e retorna nulo se quiser continuar na navegação, ou retornar a viewId para ir para outra página. Veja um exemplo de utilização desse método:


@Override
public String requestAction() {
	try{
		if("nova".equals(idPessoa)){
			pessoa = new Pessoa();
			return null;
		}
		
		Long id = Long.parseLong(idPessoa);
		pessoa = pessoaService.findBy(Pessoa.class, id);
		if(pessoa == null) throw new NumberFormatException();
		return null;
	}catch(NumberFormatException nfe){
		addMsgErro(messages.globalRegistroNaoEncontrado());
		return Navigate.to(ListarPessoasController.class).withoutRedirect().build();
	}
}

Não se esqueça de que os parâmetros injetados em seu bean também deve possuir a anotação @Deferred para que a injeção siga o escopo correto do bean. Exemplo:

@Parameter
@Deferred
private String idPessoa;


SecureHttpConfigurationProvider
Outro suporte que a arquitetura fornece é a classe SecureHttpConfigurationProvider que ajuda na configuração do Rewrite provendo uma melhor segurança para as aplicações.


Caso o usuário tente navegar para uma url que não está mapeada pelo Rewrite, o status 404 será retornado. Para que ainda seja possível o mapeamento de urls via anotação, nessa classe foi informado a prioridade 101, pois as anotações possuem prioridade 100.

Desta forma, caso o usuário tente navegar para uma url que não foi definida nem nas anotações e nem via provider, o status 404 será retornado.

Para utilizar a classe é necessário estendê-la. Confira:

@RewriteConfiguration
public class RewriteConfigurationProvider extends SecureHttpConfigurationProvider {

	@Override
	public ConfigurationBuilder getConfigurationBuilder(final ServletContext context) {
		return ConfigurationBuilder.begin()
				
				.addRule(Join.path("/").to("/view/home.xhtml"))
				.addRule(Join.path("/403").to("/view/403.xhtml").withInboundCorrection())
				.addRule(Join.path("/404").to("/view/404.xhtml").withInboundCorrection())
				.addRule(Join.path("/500").to("/view/500.xhtml").withInboundCorrection())
				
		;
	}

}

Assim, o usuário não poderá navegar para as páginas diretamente (http://localhost:8080/example/view/home.xhtml), apenas via url amigável.

Conversores

A arquitetura traz uma série de conversores que são comumente criados no desenvolvimento das aplicação, principalmente brasileiras. Praticamente todos os conversores criados são utilizados em componentes que a arquitetura provê, logo não precisariam ser utilizados diretamente, mas sim, via componente.

Entretanto, será demonstrado como utilizá-los independentemente, sem ser via componente.

Conversor de CNPJ
@FacesConverter("br.com.surittec.suricdi.faces.converter.CnpjConverter")
public class CnpjConverter implements Converter
Utilização
<f:converter converterId="br.com.surittec.suricdi.faces.converter.CnpjConverter"/>
Conversor de CPF
@FacesConverter("br.com.surittec.suricdi.faces.converter.CpfConverter")
public class CpfConverter implements Converter
Utilização
<f:converter converterId="br.com.surittec.suricdi.faces.converter.CpfConverter"/>
Conversor de Data
Utilize o componente, será bem mais fácil para utilizar todos os recursos!
@FacesConverter("br.com.surittec.suricdi.faces.converter.DateConverter")
public class DateConverter implements Converter
Utilização
<f:attribute name="DateConverter.PATTERN_ATTR" value="dd/MM/yyyy"/>
<f:converter converterId="br.com.surittec.suricdi.faces.converter.DateConverter"/>
Conversor de Strings vazias para null
Não há a necessidade de fazer nada!
@FacesConverter(forClass = String.class)
public class EmptyToNullConverter implements Converter
Conversor de Enumerações
@FacesConverter("br.com.surittec.suricdi.faces.converter.EnumConverter")
public class EnumConverter implements Converter
Utilização
<f:converter converterId="br.com.surittec.suricdi.faces.converter.EnumConverter"/>
Conversor de Numéricos
Utilize o componente, será bem mais fácil para utilizar todos os recursos!
@FacesConverter("br.com.surittec.suricdi.faces.converter.NumberConverter")
public class NumberConverter implements Converter
Utilização
<f:converter converterId="br.com.surittec.suricdi.faces.converter.NumberConverter" />
<f:attribute name="locale" value="#{locale}"/>
<f:attribute name="integerDigits" value="#{integerDigits}"/>
<f:attribute name="fractionDigits" value="#{fractionDigits}"/>
<f:attribute name="convertionType" value="#{convertionType}"/>
Conversor de Objetos
@FacesConverter("br.com.surittec.suricdi.faces.converter.SimpleObjectConverter")
public class SimpleObjectConverter implements Converter
Utilização
<f:converter converterId="br.com.surittec.suricdi.faces.converter.SimpleObjectConverter"/>

Validadores

Componentes

Utilitários

Clone this wiki locally