segunda-feira, 22 de novembro de 2010

8.COMPOSITE VIEW



Objetivo:
Criar um componente de View a partir de Views menores para dividir as responsabilidades, simplificar a construção da interface e permitir o reuso de componentes da View.

  
 
Descrição do problema

Páginas Web sofisticadas dividem seu conteúdo em várias partes, que tem função e tempo de vida diferentes;
Podem ser manipuladas por pessoas diferentes já que cada seção tem finalidade, escopo e duração diferentes;
Se a página for gerada a partir de uma única View que concentra todo o código, a atualização da página é dificultada;
É difícil identificar cada parte dentro de um documento;
Há risco, quando se atualiza uma seção, de se invadir outra seção e afetar os dados.



7.FRONT CONTROLLER


Contexto
O mecanismo de movimentação da camada de apresentação pedido deve controlar e coordenar o processamento de cada usuário em várias solicitações. Tais mecanismos de controle podem ser gerenciados em qualquer forma centralizada ou descentralizada.

Problema
O sistema requer um ponto de acesso centralizado para solicitar a apresentação de camada de manipulação de apoiar a integração dos serviços do sistema, recuperação de conteúdo, gerenciamento de visualização e navegação. Quando o usuário acessa a view diretamente, sem passar por um mecanismo centralizado, dois problemas podem ocorrer:
 Cada vista é obrigada a fornecer os seus serviços próprio sistema, resultando muitas vezes em duplicado código.
 Ver a navegação é deixada à vista. Isso pode resultar em visualizar conteúdos misturados e navegação vista.
Além disso, o controle distribuído é mais difícil de manter, já que as mudanças, muitas vezes, precisam ser feitas em diversos lugares.

Forças
 Sistema comum de serviços de processamento de concluída por pedido. Por exemplo, o serviço de segurança completa verificações de autenticação e autorização.
 Lógico que é melhor tratada em um local central em vez disso é replicado dentro vistas numerosas.
 existem pontos de decisão com relação à recuperação e manipulação de dados.
 Várias visões são utilizadas para responder às solicitações de empresas similares.
 Um ponto central de contato para tratar uma solicitação pode ser útil, por exemplo, para controle e registro do andamento de um usuário através do site.
 Serviços do sistema e da lógica de gestão de exibição são relativamente sofisticados.

Solução
Use um controlador como o ponto inicial de contato para tratar uma solicitação. O controlador gerencia o tratamento do pedido, incluindo os serviços de segurança invocando como a autenticação e autorização, a delegação de processamento de negócios, gerenciar a escolha de uma visão adequada, tratamento de erros e gerenciar a seleção de estratégias de criação de conteúdo.
O controlador fornece um ponto de acesso centralizado que controla e gerencia a manipulação de pedido web. Ao centralizar os pontos de decisão e de controlo, o controlador também ajuda a reduzir a quantidade de código Java, chamada de scriptlets, embutido na página JavaServer Pages (JSP).
lógica de negócios centralizando o controle no tratamento e redução na visão promove a reutilização de código entre as requisições. É uma abordagem preferível à alternativa de código-incorporação em vários pontos de vista, porque essa abordagem pode levar a uma mais propenso a erros, reutilização pelo ambiente de copiar e colar.
Tipicamente, um controlador de coordenadas com um componente de despachante. Despachantes são responsáveis pelo gerenciamento de visualização e navegação. Assim, um distribuidor escolhe o próximo modo de exibição para o usuário e controle de vetores para o recurso. Despachantes podem ser encapsulados dentro do controlador, direta ou pode ser extraído em um componente separado.
Enquanto o padrão Front Controller sugere centralizar a manipulação de todos os pedidos, não limitar o número de manipuladores do sistema, como faz um Singleton.

Um aplicativo pode usar vários controladores em um sistema, cada um correspondente a um conjunto de serviços distintos.


Estrutura
Figura 7.1 representa o Front Controller padrão de diagrama de classe.


Participantes e Responsabilidades
Figura 7.2 mostra o diagrama de seqüência representando o padrão Front Controller. Ele descreve como o controlador processa um pedido.

 

Controller

O controlador é o ponto de contato inicial para tratar todas as solicitações no sistema. O controlador pode delegar a um ajudante para completar a autenticação e autorização de um usuário ou para iniciar a obtenção de contato.


Dispatcher
Um distribuidor é responsável pelo gerenciamento e exibição de navegação, gestão da escolha do modo de exibição ao lado de apresentar para o usuário, e fornecer o mecanismo para a vetorização de controle para este recurso.
Um despachante pode ser encapsulado dentro de um controlador ou pode ser um componente separado trabalhar em coordenação. O atendente fornece tanto estática expedição à vista ou um mais sofisticado mecanismo dinâmico de expedição.
O despachante usa o objeto RequestDispatcher (suportado na especificação do servlet) e encapsula algum processamento adicional.

Helper
Um auxiliar é responsável por ajudar uma vista ou controlador de completar a sua transformação. Assim, ajudantes têm inúmeras responsabilidades, incluindo a recolha de dados exigidos pela exibição e armazenamento deste modelo intermediário, caso em que o auxiliar é por vezes referido como um grão de valor. Além disso, os ajudantes podem adaptar este modelo de dados para uso pelo ponto de vista. Ajudantes pode atender as solicitações para os dados do ponto de vista, simplesmente fornecendo acesso aos dados brutos ou através da formatação dos dados como conteúdo da web.
Uma visão pode trabalhar com qualquer número de ajudantes, que normalmente são implementados como componentes JavaBeans (JSP 1.0) e custom tags JSP (1.1). Além disso, um ajudante pode representar um objeto de comando, um delegado (ver "Business Delegate" na página 248), ou um transformador de XSL, que é usado em combinação com uma folha de estilo para se adaptar e converter o modelo para o formulário apropriado.

View
Uma visão representa e exibe informações para o cliente. A visão recupera informações de um modelo. vistas apoio Helpers, encapsulando e adaptar o modelo de dados subjacente para utilização no ecrã.

Strategies
Existem várias estratégias para a implementação de um controlador.

Servlet Front Strategy
Esta estratégia sugere execução do controlador como uma servlet. Embora semanticamente equivalente, é preferível à Frente JSP estratégia. O controlador gerencia os aspectos do tratamento de solicitações que estão relacionados ao processamento de negócios e fluxo de controle. Essas responsabilidades são relacionados, mas logicamente independentes, exibir a formatação, e são mais apropriadamente encapsulada em um servlet, e não em uma página JSP.
O Servlet Frente estratégia tem alguns inconvenientes potenciais.Em particular, não aproveitar alguns dos utilitários JSP ambiente runtime, como o preenchimento automático de parametros do pedido em propriedades ajudante. Felizmente, essa desvantagem é mínima, porque é relativamente fácil criar ou obter utilitários similares para uso geral. Há também a possibilidade de que a funcionalidade de alguns dos utilitários JSP podem ser incluídos como recursos servlet padrão em uma futura versão da especificação do servlet. Exemplo 7.9 é um exemplo da Frente Servlet estratégia.
Exemplo Servlet 7.9 Código de exemplo Frente Estratégia
public class EmployeeController extends HttpServlet {
  // Initializes the servlet.
  public void init(ServletConfig config) throws
    ServletException {
    super.init(config);
  }

  // Destroys the servlet.
  public void destroy() {
  }

  /** Processes requests for both HTTP 
   * <code>GET</code> and <code>POST</code> methods.
   * @param request servlet request
   * @param response servlet response
   */
  protected void processRequest(HttpServletRequest
    request, HttpServletResponse response)
    throws ServletException, java.io.IOException {
    String page;

    /**ApplicationResources provides a simple API
     * for retrieving constants and other
     * preconfigured values**/
    ApplicationResources resource =
      ApplicationResources.getInstance();
    try {

      // Use a helper object to gather parameter
      // specific information.
      RequestHelper helper = new
         RequestHelper(request);

      Command cmdHelper= helper.getCommand();

      // Command helper perform custom operation
      page = cmdHelper.execute(request, response);

    }
    catch (Exception e) {
      LogManager.logMessage(
        "EmployeeController:exception : " +
        e.getMessage());
      request.setAttribute(resource.getMessageAttr(),  
        "Exception occurred : " + e.getMessage());
      page = resource.getErrorPage(e);
    }
    // dispatch control to view
    dispatch(request, response, page);
  }

  /** Handles the HTTP <code>GET</code> method.
   * @param request servlet request
   * @param response servlet response
   */
  protected void doGet(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, java.io.IOException {
      processRequest(request, response);
  }

  /** Handles the HTTP <code>POST</code> method.
   * @param request servlet request
   * @param response servlet response
   */
  protected void doPost(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, java.io.IOException {
        processRequest(request, response);
  }

  /** Returns a short description of the servlet */
  public String getServletInfo() {
    return "Front Controller Pattern" +
      " Servlet Front Strategy Example";
  }

  protected void dispatch(HttpServletRequest request,
    HttpServletResponse response,
    String page)
  throws  javax.servlet.ServletException,
    java.io.IOException {
    RequestDispatcher dispatcher =
      getServletContext().getRequestDispatcher(page);
    dispatcher.forward(request, response);
  }
}



6. CORE J2EE Patterns – INTERCEPTING FILTER



Contexto

O mecanismo de movimentação da camada de apresentação recebe pedido de diversos tipos de solicitações, as quais exigem variados tipos de tratamento.

Alguns dos pedidos são simplesmente encaminhadas para o componente manipulador adequado, enquanto outros pedidos devem ser modificados, auditadas ou não comprimido antes de serem tratados posteriormente.
Problema
Pré-processamento e pós-processamento de uma solicitação de cliente da Web e de resposta são necessários.
Quando um pedido entra em um aplicativo da Web, que muitas vezes precisam passar por testes de entrada diversos, antes da fase de processamento principal. Por exemplo,
Tem o cliente foi autenticado?
O cliente tem uma sessão válida?
É o endereço IP do cliente de uma rede confiável?
Será que o caminho de solicitação violar quaisquer restrições?
Qual a codificação que o uso do cliente para enviar os dados?
Nós apoiamos o tipo de navegador do cliente?
Alguns desses cheques são testes, resultando em uma resposta sim ou não que determina se o processamento continuará. Outras verificações manipular o fluxo de dados recebidos em uma forma adequada para o processamento.
A solução clássica consiste de uma série de verificações condicionais, com toda a verificação não abortar o pedido. If / else é uma estratégia padrão, mas essa solução leva à fragilidade de código e um estilo de copiar e colar da programação, pois o fluxo da filtragem e da ação dos filtros é compilado no aplicativo.
A chave para resolver este problema de uma forma flexível e discreto é ter um mecanismo simples para adicionar e remover componentes de processamento, em que cada componente conclui uma ação específica de filtragem.
Forças
 processamento comum, como a verificação do esquema de codificação de dados ou informações de log sobre cada pedido, por solicitação completa.
 Centralização da lógica comum é desejado

 
Os serviços devem ser fáceis de adicionar ou remover discretamente, sem afetar os componentes existentes, de modo que eles podem ser usados em uma variedade de combinações, como
 Registo e autenticação
 transformação e depuração de saída para um cliente específico
 esquema de codificação Descompactando e conversão de entrada
Solução
Crie filtros pluggable para processar serviços comuns de forma padrão, sem exigir alterações no código do núcleo do pedido de transformação.
Os filtros de interceptar as solicitações de entrada e respostas de saída, permitindo que o pré-processamento e pós-processamento. Somos capazes de adicionar ou remover estes filtros discretamente, sem exigir alterações no nosso código existente.
Nós somos capazes, com efeito, para decorar o nosso processamento principal com uma variedade de serviços comuns, como segurança, registro de depuração, e assim por diante. Esses filtros são componentes que são independentes do código do aplicativo principal, e eles podem ser adicionados ou removidos de forma declarativa. Por exemplo, um arquivo de configuração de implantação pode ser modificada para criar uma cadeia de filtros. O mesmo arquivo de configuração pode incluir um mapeamento de URLs específicos para essa cadeia de filtro. Quando um cliente solicita um recurso que corresponde a esse mapeamento URL configurada, os filtros da cadeia são cada processados em ordem antes de o recurso solicitado alvo é invocado.


EstruturaFigura 6.1 representa o padrão Intercepting Filter.




PARTICIPANTES E RESPONSABILIDADES
Figura 6.2 representa o padrão Intercepting Filter.


FilterManagerO FilterManager gerencia o processamento do filtro. Cria o FilterChain com os filtros adequados, na ordem correta, e inicia o processamento.FilterChainO FilterChain é uma coleção ordenada de filtros independentes.FilterOne, FilterTwo, FilterThreeEstes são os filtros individuais que são mapeados para um alvo. O FilterChain coordena o seu tratamento.AlvoO alvo é o recurso solicitado pelo cliente.

Estratégias
Estratégia Custom FilterO filtro é implementado através de uma estratégia personalizada definida pelo desenvolvedor. Isso é menos flexível e menos poderoso do que o padrão preferido Filtro estratégia, que é apresentado na próxima seção e só está disponível em embalagens suportam a especificação servlet 2.3. O Custom Filter estratégia é menos potente, porque não pode fornecer para o acondicionamento de objetos de solicitação e resposta de uma forma padrão e portátil. Além disso, o objeto do pedido não pode ser modificado, e algum tipo de mecanismo de buffer deve ser introduzida se os filtros são para controlar o fluxo de saída. Para implementar a Estratégia Custom Filter, o desenvolvedor pode usar o padrão Decorator [GoF] para embrulhar filtros em torno da lógica do núcleo de processamento de pedido. Por exemplo, pode haver uma depuração do filtro que envolve um filtro de autenticação. Exemplo 6.1 e Exemplo 6.2 mostram como este mecanismo pode ser criado por meio de programação:
Exemplo 6.1 Implementação de um Filtro - de Depuração
public class DebuggingFilter implements Processor {
  private Processor target;

  public DebuggingFilter(Processor myTarget) {
    target = myTarget;
  }

  public void execute(ServletRequest req,
  ServletResponse res) throws IOException,
    ServletException    {
    //Do some filter processing here, such as
    // displaying request parameters
    target.execute(req, res);
  }
}Ouvir
Ler foneticamente


Exemplo 6.2 Implementação de um Filtro – Processador Core
public class CoreProcessor implements Processor {
  private Processor target;
  public CoreProcessor()   {
    this(null);
  }

  public CoreProcessor(Processor myTarget)   {
    target = myTarget;
  }

  public void execute(ServletRequest req,
      ServletResponse res) throws IOException,
      ServletException   {
    //Do core processing here
  }
}

No servlet controlador, nós delegamos a um método chamado processRequest para lidar com as solicitações de entrada, como mostrado no Exemplo 6.3.

Exemplo 6.3 o tratamento dos pedidos
public void processRequest(ServletRequest req,
  ServletResponse res)
  throws IOException, ServletException {
  Processor processors = new DebuggingFilter(
    new AuthenticationFilter(new CoreProcessor()));
  processors.execute(req, res);

  //Then dispatch to next resource, which is probably
  // the View to display
  dispatcher.dispatch(req, res);
}

Para fins de exemplo apenas, imagine que cada componente de processamento escreve na saída padrão quando ele é executado. Exemplo 7.4 mostra a saída de execução possível.
Exemplo 6.4 Mensagens escrito na saída padrão
Depuração de pré-processamento filtro concluída ...
Autenticação de processamento do filtro concluída ...
processamento Core concluída ...Depuração filtro de pós-processamento foi concluído ...


Uma cadeia de processadores é executado em ordem. Cada processador, exceto para o último na cadeia, é considerado um filtro. O componente final do processador é onde nós encapsular o processamento central que queremos preencher, para cada pedido. Dado este projeto, vamos ter de alterar o código na classe CoreProfessor, bem como em quaisquer classes de filtro, quando queremos modificar a forma como lidamos com as solicitações. Figura 6.3 é um diagrama de seqüência que descreve o fluxo de controle quando, utilizando o código do filtro do Exemplo 6.1, Exemplo 6.2 e Exemplo 6.3.




Observe que quando usamos uma aplicação decorador, cada filtro chama na próxima filtro diretamente, embora utilizando uma interface genérica. Alternativamente, esta estratégia pode ser implementada usando um FilterManager e FilterChain. Neste caso, esses dois componentes coordenar e gerenciar o processamento do filtro e os filtros individuais não se comunicam uns com os outros diretamente. Este projeto se aproxima de uma aplicação servlet 2.3-compatível, embora ainda seja uma estratégia personalizada. Exemplo 6.5 é o anúncio de um tal FilterManager uma classe que cria um FilterChain, que é mostrado no Exemplo 6.6. O FilterChain adiciona filtros para a cadeia na ordem apropriada (para efeitos de concisão, isso é feito no construtor FilterChain, mas seria feito normalmente no lugar do comentário), os processos dos filtros e, finalmente, processa o recurso de destino. Figura 6.4 é um diagrama de seqüência para esse código.





Exemplo 6.5 FilterManager – Estratégia Filtro personalizado
public class FilterManager {
  public void processFilter(Filter target,
    javax.servlet.http.HttpServletRequest request,
    javax.servlet.http.HttpServletResponse response)
    throws javax.servlet.ServletException,
      java.io.IOException       {                   
    FilterChain filterChain = new FilterChain();
                   
    // The filter manager builds the filter chain here
    // if necessary

    // Pipe request through Filter Chain
    filterChain.processFilter(request, response);

    //process target resource
    target.execute(request, response);
  }
}

FilterChain Exemplo 6.6 - Estratégia Filtro personalizado
public class FilterChain {
  // filter chain
  private Vector myFilters = new Vector();

  // Creates new FilterChain
  public FilterChain()  {
    // plug-in default filter services for example
    // only. This would typically be done in the
    // FilterManager, but is done here for example
    // purposes
    addFilter(new DebugFilter());
    addFilter(new LoginFilter());
    addFilter(new AuditFilter());
  }

  public void processFilter(
    javax.servlet.http.HttpServletRequest request,
    javax.servlet.http.HttpServletResponse response)
  throws javax.servlet.ServletException,
    java.io.IOException         {
    Filter filter;

    // apply filters
    Iterator filters = myFilters.iterator();
    while (filters.hasNext())
    {
      filter = (Filter)filters.next();
      // pass request & response through various
      // filters
      filter.execute(request, response);
    }
  }

  public void addFilter(Filter filter)  {
    myFilters.add(filter);
  }
}

Esta estratégia não nos permitem criar filtros que são tão flexíveis ou tão poderoso quanto gostaríamos. Por um lado, os filtros são adicionados e removidos de forma programática. Enquanto nós poderíamos escrever um mecanismo de propriedade para a manipulação adição e remoção de filtros através de um arquivo de configuração, ainda não teria nenhuma maneira de envolver os objetos de requisição e resposta. Além disso, sem um mecanismo sofisticado de buffer, esta estratégia não prevê postprocessing flexível.
O Padrão de filtro Estratégia fornece soluções para estas questões, aproveitando os recursos da especificação Servlet 2.3, que forneceu uma solução padrão para o dilema do filtro.
Standard Estratégia Filtro
Os filtros são controladas declarativamente usando um descritor de implementação, conforme descrito na especificação do servelet versão 2.3, que, como desta escrita, está em fase de projeto final.
A especificação Servlet 2.3 inclui um mecanismo padrão para a construção de cadeias de filtro e discretamente adição e remoção de filtros das cadeias. Os filtros são construídos em torno de interfaces e, acrescentado ou retirado de uma forma declarativa, modificando o descritor de implementação de uma aplicação web.
Nosso exemplo para essa estratégia será criar um filtro que pré-processa os pedidos de qualquer tipo de codificação de forma que cada pedido pode ser tratado de forma semelhante em nossa solicitação núcleo manipulação de código. Por que isso pode ser necessário? formulários HTML que incluem um upload de arquivo usar um tipo de codificação diferente da maioria das formas. Assim, os dados do formulário que acompanha o upload não está disponível através de simples getParameter () invocações. Então, criamos dois filtros que os pedidos preprocess, traduzindo todos os tipos de codificação em um único formato consistente. O formato que escolhemos é ter todos os dados do formulário disponível como atributos pedido.
Um filtro manipula o formulário padrão de codificação do tipo application / x-www-form-urlencoded ea outra manipula o menos comum tipo de codificação multipart / form-data, que é utilizado para as formas que incluem o upload de arquivos. Os filtros de traduzir todos os dados do formulário para solicitação de atributos, de modo que o núcleo mecanismo de manipulação de pedido pode trabalhar com todos os pedidos da mesma forma, em vez de com a embalagem especial para diferentes codificações.
Exemplo 6.8 mostra um filtro que traduz os pedidos usando a aplicação do regime comum de codificação do formulário. Exemplo 6.9 mostra o filtro que controla a tradução dos pedidos que usam o esquema de codificação de forma concatenada. O código para estes filtros se baseia na versão final da especificação do servlet, versão 2.3. Uma base de filtro é utilizado, bem como, a partir da qual ambos os filtros de herdar (veja a seção "Base de Filtro Estratégia"). A base do filtro, mostrado no Exemplo 6.7, fornece o comportamento padrão para o padrão de métodos de retorno de filtro.
Exemplo 6.7 Base Filtro – Estratégia Filtro Padrão
public class BaseEncodeFilter implements
      javax.servlet.Filter {
  private javax.servlet.FilterConfig myFilterConfig;

  public BaseEncodeFilter()     {  }

  public void doFilter(
    javax.servlet.ServletRequest servletRequest,
    javax.servlet.ServletResponse servletResponse,
    javax.servlet.FilterChain filterChain)
  throws java.io.IOException,
    javax.servlet.ServletException {
    filterChain.doFilter(servletRequest,
        servletResponse);
  }

  public javax.servlet.FilterConfig getFilterConfig()
  {
    return myFilterConfig;
  }
   
  public void setFilterConfig(
    javax.servlet.FilterConfig filterConfig) {
      myFilterConfig = filterConfig;
  }
}

Exemplo 6.8 StandardEncodeFilter – Standard Filter Strategy
public class StandardEncodeFilter
  extends BaseEncodeFilter {
  // Creates new StandardEncodeFilter
  public StandardEncodeFilter()   {  }

  public void doFilter(javax.servlet.ServletRequest
    servletRequest,javax.servlet.ServletResponse
    servletResponse,javax.servlet.FilterChain
    filterChain)
  throws java.io.IOException,
    javax.servlet.ServletException {

    String contentType =
      servletRequest.getContentType();
    if ((contentType == null) ||
      contentType.equalsIgnoreCase(
        "application/x-www-form-urlencoded"))     {
      translateParamsToAttributes(servletRequest,
        servletResponse);
    }

    filterChain.doFilter(servletRequest,
      servletResponse);
  }

  private void translateParamsToAttributes(
    ServletRequest request, ServletResponse response)
  {
    Enumeration paramNames =
        request.getParameterNames();

    while (paramNames.hasMoreElements())     {
      String paramName = (String)
          paramNames.nextElement();

      String [] values;

      values = request.getParameterValues(paramName);
      System.err.println("paramName = " + paramName);
      if (values.length == 1)
        request.setAttribute(paramName, values[0]);
      else
        request.setAttribute(paramName, values);
    }
 }
}

Example 6.9 MultipartEncodeFilter – Standard Filter Strategy
 public class MultipartEncodeFilter extends
  BaseEncodeFilter {
  public MultipartEncodeFilter() { }
  public void doFilter(javax.servlet.ServletRequest
    servletRequest, javax.servlet.ServletResponse
    servletResponse,javax.servlet.FilterChain
    filterChain)
  throws java.io.IOException,
    javax.servlet.ServletException {
    String contentType =
      servletRequest.getContentType();  
    // Only filter this request if it is multipart
    // encoding               
    if (contentType.startsWith(
                "multipart/form-data")){
      try {
        String uploadFolder =
          getFilterConfig().getInitParameter(
              "UploadFolder");
        if (uploadFolder == null) uploadFolder = ".";

        /** The MultipartRequest class is:
        * Copyright (C) 2001 by Jason Hunter
        * <jhunter@servlets.com>. All rights reserved.
        **/
        MultipartRequest multi = new
          MultipartRequest(servletRequest,
                           uploadFolder,
                           1 * 1024 * 1024 );
        Enumeration params =
                 multi.getParameterNames();
        while (params.hasMoreElements()) {
          String name = (String)params.nextElement();
          String value = multi.getParameter(name);
          servletRequest.setAttribute(name, value);
        }                        

        Enumeration files = multi.getFileNames();
        while (files.hasMoreElements()) {
          String name = (String)files.nextElement();
          String filename = multi.getFilesystemName(name);
          String type = multi.getContentType(name);
          File f = multi.getFile(name);
          // At this point, do something with the
          // file, as necessary
        }
      }
      catch (IOException e)
      {
        LogManager.logMessage(
          "error reading or saving file"+ e);
      }
    } // end if
    filterChain.doFilter(servletRequest,
                         servletResponse);
  } // end method doFilter()
}

O trecho a seguir no Exemplo 6.10 é do descritor de implantação para o aplicativo da Web que contêm este exemplo. Ele mostra como estes dois filtros são registrados e mapeados a um recurso, neste caso um servlet simples teste. Além disso, o diagrama de seqüência para este exemplo é mostrado na Figura 6.5.
Exemplo de descritor de implementação 6.10 – Estratégia Filtro Padrão
.
.
.
<filter>
    <filter-name>StandardEncodeFilter</filter-name>
    <display-name>StandardEncodeFilter</display-name>
    <description></description>
    <filter-class> corepatterns.filters.encodefilter.
            StandardEncodeFilter</filter-class>
  </filter>
  <filter>
    <filter-name>MultipartEncodeFilter</filter-name>
    <display-name>MultipartEncodeFilter</display-name>
    <description></description>
    <filter-class>corepatterns.filters.encodefilter.
            MultipartEncodeFilter</filter-class>
    <init-param>
      <param-name>UploadFolder</param-name>
      <param-value>/home/files</param-value>
    </init-param>
 </filter>
.
.
.
<filter-mapping>
    <filter-name>StandardEncodeFilter</filter-name>
    <url-pattern>/EncodeTestServlet</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>MultipartEncodeFilter</filter-name>
    <url-pattern>/EncodeTestServlet</url-pattern>
  </filter-mapping>
.
.


O StandardEncodeFilter eo controle de interceptação MultiPartEncodeFilter quando um cliente faz uma solicitação para o servlet controlador. O recipiente cumpre o papel de gestor de filtro e controle de vetores para esses filtros, invocando seus métodos doFilter. Depois de completar o seu processamento, controle de cada filtro passa à sua FilterChain contendo, que instrui para executar o próximo filtro. Uma vez que ambos os filtros de ter recebido e, posteriormente, renunciou ao controle, o próximo componente a receber o recurso de controle é alvo real, neste caso o servlet controlador.
Filtros, como suporte na versão 2.3 da especificação servlet, também envolvendo o pedido de apoio e objetos resposta. Este recurso fornece um mecanismo muito mais poderoso que pode ser construído utilizando a aplicação personalizada sugerido pelo Filtro personalizado estratégia. É claro que uma abordagem híbrida que combina as duas estratégias poderiam ser construídas, bem como, mas ainda falta o poder do Filtro Standard estratégia, apoiadas pela especificação servlet.
Base Estratégia Filtro                     
A base do filtro serve como uma superclasse comum para todos os filtros. As características comuns podem ser encapsuladas na base do filtro e compartilhados entre todos os filtros. Por exemplo, uma base de filtro é um bom lugar para se incluir o comportamento padrão para os métodos de callback contêiner no filtro Declarada estratégia. Exemplo 6.11 mostra como isso pode ser feito.


Base Exemplo 6.11 Estrategia Filtro
public class BaseEncodeFilter implements
  javax.servlet.Filter {
  private javax.servlet.FilterConfig myFilterConfig;
       
  public BaseEncodeFilter()             {       }

  public void doFilter(javax.servlet.ServletRequest    
    servletRequest,javax.servlet.ServletResponse
    servletResponse, javax.servlet.FilterChain
    filterChain) throws java.io.IOException,
    javax.servlet.ServletException {

    filterChain.doFilter(servletRequest,
      servletResponse);
  }

  public javax.servlet.FilterConfig getFilterConfig() {
    return myFilterConfig;
  }
   
  public void
  setFilterConfig(javax.servlet.FilterConfig
    filterConfig) {
    myFilterConfig = filterConfig;
  }
}

Template Filter Strategy
Usando uma base de filtro a partir do qual todos os outros herdam permite que a classe base para fornecer modelo de método [GOF] e suas funcionalidades. Neste caso, a base de filtro é usado para ditar as etapas gerais que devem completar cada filtro, deixando os detalhes de como concluir essa etapa para cada subclasse de filtro. Normalmente, estas seriam grosseiramente definido, métodos básicos que simplesmente impor uma estrutura limitada de cada modelo. Esta estratégia pode ser combinada com qualquer outra estratégia de filtro, também. Os anúncios no Exemplo 6.12 e Exemplo 6,13 mostram como usar esta estratégia com o filtro Declarada estratégia.
Exemplo de 6,12 mostra uma base de filtro chamado TemplateFilter, como segue.

Exemplo 6.12 usando uma estratégia de filtro de template
public abstract class TemplateFilter implements
  javax.servlet.Filter {
  private FilterConfig filterConfig;

  public void setFilterConfig(FilterConfig fc) {
    filterConfig=fc;
  }

  public FilterConfig getFilterConfig()         {
    return filterConfig;
  }

  public void doFilter(ServletRequest request,
    ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
    // Common processing for all filters can go here
    doPreProcessing(request, response, chain);

    // Common processing for all filters can go here
    doMainProcessing(request, response, chain);

    // Common processing for all filters can go here
    doPostProcessing(request, response, chain);

    // Common processing for all filters can go here

    // Pass control to the next filter in the chain or
    // to the target resource
    chain.doFilter(request, response);
  }
  public void doPreProcessing(ServletRequest request,  
    ServletResponse response, FilterChain chain) {
  }

  public void doPostProcessing(ServletRequest request,
    ServletResponse response, FilterChain chain) {
  }

  public abstract void doMainProcessing(ServletRequest
   request, ServletResponse response, FilterChain
   chain);
}

Dada esta definição de classe para TemplateFilter, cada filtro é implementado como uma subclasse que só deve implementar o método doMainProcessing. Estas subclasses têm a opção, no entanto, de todos os três métodos de execução, se o desejarem. Exemplo 6,13 é um exemplo de uma subclasse de filtro que implementa o método de uma obrigatória (ditada por nosso modelo de filtro) eo método de pré-processamento opcionais. Além disso, um diagrama de seqüência para a utilização desta estratégia é mostrado na Figura 6.6.


Example 6.13 Debugging Filter
public class DebuggingFilter extends TemplateFilter {
  public void doPreProcessing(ServletRequest req,
    ServletResponse res, FilterChain chain) {
    //do some preprocessing here
  }

  public void doMainProcessing(ServletRequest req,
    ServletResponse res, FilterChain chain) {
    //do the main processing;
  }
}




No diagrama de seqüência na Figura 6.6, as subclasses de filtro, como DebuggingFilter, definir o processamento específicos, substituindo o método abstrato do MainProcessing e, opcionalmente, do PreProcessing e do PostProcessing. 
Assim, o modelo de filtro impõe uma estrutura para cada filtro de processamento, bem como proporcionar um local para encapsular o código que é comum a todos os filtros.
Consequências
Centraliza o controle de manipuladores acoplados de forma flexível
Filtros de fornecer um lugar central para o tratamento de processamento em várias solicitações, como faz um controlador. Os filtros são mais adequados às solicitações e respostas de massagem para o tratamento final de um recurso de destino, tal como um controlador. Adicionalmente, um controlador, muitas vezes amarra a gestão de numerosos independentes serviços comuns, como autenticação, criptografia de registro, e assim por diante, enquanto para manipuladores de filtragem permite muito mais flexível, que podem ser combinadas em várias combinações.
 
Melhora a Reutilização

Filtros de promover a aplicação de particionamento mais limpo e encoraja a reutilização. Esses interceptores são conectáveis transparente adicionado ou retirado a partir do código existente, e devido a sua interface padrão, eles trabalham em qualquer combinação e são reutilizáveis para apresentações variadas.
 
Configuração declarativa e flexível


Diversos serviços são combinados em permutas variadas, sem um único recompilar o código base do núcleo.
 
Compartilhamento de informações é ineficiente


O compartilhamento de informações entre os filtros podem ser ineficientes, uma vez que, por definição, cada filtro é acoplado livremente. Se grandes quantidades de informação deve ser compartilhada entre os filtros, então esta abordagem pode ser dispendiosa.
Padrões relacionados
Front Controller
O controlador resolve alguns problemas semelhantes, mas é mais adequado ao tratamento de processamento central.
 
Decorator [GoF]
O padrão Intercepting Filter está relacionado com o padrão Decorator, que prevê invólucros dinamicamente pluggable.
 
Template Method [GoF]
O modelo padrão de método é usado para implementar o modelo de Filtro de estratégia.
 
Interceptor [POSA2]
O padrão Intercepting Filter está relacionado ao padrão Interceptor, que permite que os serviços sejam adicionados de forma transparente e acionado automaticamente.
 
Tubos e filtros [POSA1]
O padrão Intercepting Filter está relacionado ao padrão de pipes e filtros.