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

A arquitetura traz uma série de validadores que são comumente criados no desenvolvimento das aplicação, principalmente brasileiras. Praticamente todos os validadores 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.

Validador de CNPJ
@FacesValidator("br.com.surittec.suricdi.faces.validator.CnpjValidator")
public class CnpjValidator implements Validator
Utilização
<f:validator validatorId="br.com.surittec.suricdi.faces.validator.CnpjValidator"/>
Validador de CPF
@FacesValidator("br.com.surittec.suricdi.faces.validator.CpfValidador")
public class CpfValidador implements Validator
Utilização
<f:validator validatorId="br.com.surittec.suricdi.faces.validator.CpfValidador"/>
Validador de Data
Utilize o componente, será bem mais fácil para utilizar todos os recursos!
@FacesValidator("br.com.surittec.suricdi.faces.validator.DateValidator")
public class DateValidator implements Validator
Utilização
<f:validator validatorId="br.com.surittec.suricdi.faces.validator.DateValidator"/>
<f:attribute name="beforeThen" value="#{beforeThen}"/>
<f:attribute name="beforeThenMessage" value="#{beforeThenMessage}"/>
<f:attribute name="afterThen" value="#{afterThen}"/>
<f:attribute name="afterThenMessage" value="#{afterThenMessage}"/>
Validador de Email
@FacesValidator("br.com.surittec.suricdi.faces.validator.EmailValidator")
public class EmailValidator implements Validator
Utilização
<f:validator validatorId="br.com.surittec.suricdi.faces.validator.EmailValidator"/>
Validador de Comparação de Campos
Utilize o componente, será bem mais fácil para utilizar todos os recursos!
@FacesValidator("br.com.surittec.suricdi.faces.validator.MatchValidator")
public class MatchValidator implements Validator
Utilização
<f:validator validatorId="br.com.surittec.suricdi.faces.validator.MatchValidator"/>
<f:attribute name="with" value="#{with}"/>
<f:attribute name="message" value="#{message}"/>

Componentes

Para facilitar o uso dos conversores e dos validadores a arquitetura provê uma série de componentes facelets que podem ser usados em conjunto com os diversos componentes (JSF, Primefaces e etc) de forma harmoniosa e não intrusiva.

Além disso, alguns componentes já incluem máscaras jquery em campos que necessitam, como cpf, cnpj, data e numérico. Ainda sobre máscaras, o componente InputMask do Primefaces foi sobrescrito para utilização com máscaras jquery do meiomask, que possuem um poder muito maior que as máscaras padrões do Primefaces.

Veja como utilizar máscaras meiomask em componentes Primefaces:

<p:inputMask id="cnpj" value="#{controller.cnpj}" mask="mask:'99.999.999/9999-99'"/>

Para utilização dos componentes da arquitetura é necessário que, primeiramente, o namespace seja definido:

xmlns:s="http://www.surittec.com.br/jsf/ui"
xmlns:sf="http://www.surittec.com.br/jsf/fn"

Utilitários

Clone this wiki locally