6. CORE J2EE Patterns – INTERCEPTING FILTER
Autor: Guilherme Gabriel | Publicado: 2010-11-22T13:00:00-08:00


﻿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
&nbsp;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.
&nbsp;Centralização da lógica comum é desejado
&nbsp;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
&nbsp;Registo e autenticação
&nbsp;transformação e depuração de saída para um cliente específico
&nbsp;esquema de codificação Descompactando e conversão de entradaSoluçãoCrie 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 RESPONSABILIDADESFigura 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égiasEstraté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çãopublic class DebuggingFilter implements Processor {&nbsp; private Processor target;
&nbsp; public DebuggingFilter(Processor myTarget) {&nbsp;&nbsp;&nbsp; target = myTarget;&nbsp; }
&nbsp; public void execute(ServletRequest req, &nbsp; ServletResponse res) throws IOException, &nbsp;&nbsp;&nbsp; ServletException&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; //Do some filter processing here, such as &nbsp;&nbsp;&nbsp; // displaying request parameters&nbsp;&nbsp;&nbsp; target.execute(req, res);&nbsp; }}OuvirLer foneticamente

Exemplo 6.2 Implementação de um Filtro – Processador Corepublic class CoreProcessor implements Processor {&nbsp; private Processor target;&nbsp; public CoreProcessor()&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; this(null);&nbsp; }
&nbsp; public CoreProcessor(Processor myTarget)&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; target = myTarget;&nbsp; }
&nbsp; public void execute(ServletRequest req, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ServletResponse res) throws IOException, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ServletException&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; //Do core processing here&nbsp; }}
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 pedidospublic void processRequest(ServletRequest req, &nbsp; ServletResponse res) &nbsp; throws IOException, ServletException {&nbsp; Processor processors = new DebuggingFilter( &nbsp;&nbsp;&nbsp; new AuthenticationFilter(new CoreProcessor()));&nbsp; processors.execute(req, res);
&nbsp; //Then dispatch to next resource, which is probably &nbsp; // the View to display&nbsp; 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 personalizadopublic class FilterManager {&nbsp; public void processFilter(Filter target, &nbsp;&nbsp;&nbsp; javax.servlet.http.HttpServletRequest request, &nbsp;&nbsp;&nbsp; javax.servlet.http.HttpServletResponse response) &nbsp;&nbsp;&nbsp; throws javax.servlet.ServletException, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.io.IOException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; FilterChain filterChain = new FilterChain();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // The filter manager builds the filter chain here &nbsp;&nbsp;&nbsp; // if necessary
&nbsp;&nbsp;&nbsp; // Pipe request through Filter Chain&nbsp;&nbsp;&nbsp; filterChain.processFilter(request, response);
&nbsp;&nbsp;&nbsp; //process target resource&nbsp;&nbsp;&nbsp; target.execute(request, response);&nbsp; }}
FilterChain Exemplo 6.6 - Estratégia Filtro personalizadopublic class FilterChain {&nbsp; // filter chain &nbsp; private Vector myFilters = new Vector();
&nbsp; // Creates new FilterChain &nbsp; public FilterChain()&nbsp; {&nbsp;&nbsp;&nbsp; // plug-in default filter services for example &nbsp;&nbsp;&nbsp; // only. This would typically be done in the &nbsp;&nbsp;&nbsp; // FilterManager, but is done here for example &nbsp;&nbsp;&nbsp; // purposes&nbsp;&nbsp;&nbsp; addFilter(new DebugFilter());&nbsp;&nbsp;&nbsp; addFilter(new LoginFilter());&nbsp;&nbsp;&nbsp; addFilter(new AuditFilter());&nbsp; }
&nbsp; public void processFilter( &nbsp;&nbsp;&nbsp; javax.servlet.http.HttpServletRequest request,&nbsp;&nbsp;&nbsp; javax.servlet.http.HttpServletResponse response)&nbsp; throws javax.servlet.ServletException, &nbsp;&nbsp;&nbsp; java.io.IOException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; Filter filter;
&nbsp;&nbsp;&nbsp; // apply filters&nbsp;&nbsp;&nbsp; Iterator filters = myFilters.iterator();&nbsp;&nbsp;&nbsp; while (filters.hasNext())&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filter = (Filter)filters.next();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // pass request &amp; response through various &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // filters&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filter.execute(request, response);&nbsp;&nbsp;&nbsp; }&nbsp; }
&nbsp; public void addFilter(Filter filter)&nbsp; {&nbsp;&nbsp;&nbsp; myFilters.add(filter);&nbsp; }}
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 FiltroOs 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ãopublic class BaseEncodeFilter implements &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; javax.servlet.Filter {&nbsp; private javax.servlet.FilterConfig myFilterConfig;
&nbsp; public BaseEncodeFilter()&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp; }
&nbsp; public void doFilter(&nbsp;&nbsp;&nbsp; javax.servlet.ServletRequest servletRequest, &nbsp;&nbsp;&nbsp; javax.servlet.ServletResponse servletResponse,&nbsp;&nbsp;&nbsp; javax.servlet.FilterChain filterChain) &nbsp; throws java.io.IOException,&nbsp;&nbsp;&nbsp; javax.servlet.ServletException {&nbsp;&nbsp;&nbsp; filterChain.doFilter(servletRequest, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;servletResponse);&nbsp; }
&nbsp; public javax.servlet.FilterConfig getFilterConfig() &nbsp; {&nbsp;&nbsp;&nbsp; return myFilterConfig; &nbsp; }&nbsp;&nbsp;&nbsp; &nbsp; public void setFilterConfig(&nbsp;&nbsp;&nbsp; javax.servlet.FilterConfig filterConfig) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myFilterConfig = filterConfig;&nbsp; }}
Exemplo 6.8 StandardEncodeFilter – Standard Filter Strategypublic class StandardEncodeFilter &nbsp; extends BaseEncodeFilter {&nbsp; // Creates new StandardEncodeFilter&nbsp; public StandardEncodeFilter()&nbsp;&nbsp; {&nbsp; }
&nbsp; public void doFilter(javax.servlet.ServletRequest &nbsp;&nbsp;&nbsp; servletRequest,javax.servlet.ServletResponse &nbsp;&nbsp;&nbsp; servletResponse,javax.servlet.FilterChain &nbsp;&nbsp;&nbsp; filterChain) &nbsp; throws java.io.IOException, &nbsp;&nbsp;&nbsp; javax.servlet.ServletException {
&nbsp;&nbsp;&nbsp; String contentType = &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; servletRequest.getContentType();&nbsp;&nbsp;&nbsp; if ((contentType == null) || &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; contentType.equalsIgnoreCase(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "application/x-www-form-urlencoded"))&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; translateParamsToAttributes(servletRequest, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; servletResponse);&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; filterChain.doFilter(servletRequest, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; servletResponse);&nbsp; }
&nbsp; private void translateParamsToAttributes(&nbsp;&nbsp;&nbsp; ServletRequest request, ServletResponse response)&nbsp; {&nbsp;&nbsp;&nbsp; Enumeration paramNames = &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request.getParameterNames();
&nbsp;&nbsp;&nbsp; while (paramNames.hasMoreElements())&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String paramName = (String) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; paramNames.nextElement();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String [] values;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; values = request.getParameterValues(paramName);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println("paramName = " + paramName);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (values.length == 1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request.setAttribute(paramName, values[0]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request.setAttribute(paramName, values);&nbsp;&nbsp;&nbsp; }&nbsp;}}
Example 6.9 MultipartEncodeFilter – Standard Filter Strategy&nbsp;public class MultipartEncodeFilter extends &nbsp; BaseEncodeFilter {&nbsp; public MultipartEncodeFilter() { }&nbsp; public void doFilter(javax.servlet.ServletRequest &nbsp;&nbsp;&nbsp; servletRequest, javax.servlet.ServletResponse &nbsp;&nbsp;&nbsp; servletResponse,javax.servlet.FilterChain &nbsp;&nbsp;&nbsp; filterChain)&nbsp; throws java.io.IOException, &nbsp;&nbsp;&nbsp; javax.servlet.ServletException {&nbsp;&nbsp;&nbsp; String contentType = &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; servletRequest.getContentType();&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Only filter this request if it is multipart &nbsp;&nbsp;&nbsp; // encoding&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (contentType.startsWith(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "multipart/form-data")){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String uploadFolder = &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getFilterConfig().getInitParameter(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "UploadFolder");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (uploadFolder == null) uploadFolder = ".";
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /** The MultipartRequest class is: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Copyright (C) 2001 by Jason Hunter &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * &lt;jhunter@servlets.com&gt;. All rights reserved. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MultipartRequest multi = new &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MultipartRequest(servletRequest, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uploadFolder,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 * 1024 * 1024 );&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Enumeration params = &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; multi.getParameterNames();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (params.hasMoreElements()) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String name = (String)params.nextElement();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String value = multi.getParameter(name);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; servletRequest.setAttribute(name, value);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Enumeration files = multi.getFileNames();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (files.hasMoreElements()) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String name = (String)files.nextElement();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String filename = multi.getFilesystemName(name);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String type = multi.getContentType(name);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File f = multi.getFile(name);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // At this point, do something with the &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // file, as necessary&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (IOException e)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LogManager.logMessage(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "error reading or saving file"+ e);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; } // end if&nbsp;&nbsp;&nbsp; filterChain.doFilter(servletRequest, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; servletResponse);&nbsp; } // 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...&lt;filter&gt;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;StandardEncodeFilter&lt;/filter-name&gt;&nbsp;&nbsp;&nbsp; &lt;display-name&gt;StandardEncodeFilter&lt;/display-name&gt;&nbsp;&nbsp;&nbsp; &lt;description&gt;&lt;/description&gt;&nbsp;&nbsp;&nbsp; &lt;filter-class&gt; corepatterns.filters.encodefilter.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StandardEncodeFilter&lt;/filter-class&gt;&nbsp; &lt;/filter&gt;&nbsp; &lt;filter&gt;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;MultipartEncodeFilter&lt;/filter-name&gt;&nbsp;&nbsp;&nbsp; &lt;display-name&gt;MultipartEncodeFilter&lt;/display-name&gt;&nbsp;&nbsp;&nbsp; &lt;description&gt;&lt;/description&gt;&nbsp;&nbsp;&nbsp; &lt;filter-class&gt;corepatterns.filters.encodefilter.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MultipartEncodeFilter&lt;/filter-class&gt;&nbsp;&nbsp;&nbsp; &lt;init-param&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-name&gt;UploadFolder&lt;/param-name&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;param-value&gt;/home/files&lt;/param-value&gt;&nbsp;&nbsp;&nbsp; &lt;/init-param&gt;&nbsp;&lt;/filter&gt;...&lt;filter-mapping&gt;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;StandardEncodeFilter&lt;/filter-name&gt;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/EncodeTestServlet&lt;/url-pattern&gt;&nbsp; &lt;/filter-mapping&gt;&nbsp; &lt;filter-mapping&gt;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;MultipartEncodeFilter&lt;/filter-name&gt;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/EncodeTestServlet&lt;/url-pattern&gt;&nbsp; &lt;/filter-mapping&gt;..﻿
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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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 Filtropublic class BaseEncodeFilter implements &nbsp; javax.servlet.Filter {&nbsp; private javax.servlet.FilterConfig myFilterConfig;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; public BaseEncodeFilter()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp; public void doFilter(javax.servlet.ServletRequest&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; servletRequest,javax.servlet.ServletResponse &nbsp;&nbsp;&nbsp; servletResponse, javax.servlet.FilterChain &nbsp;&nbsp;&nbsp; filterChain) throws java.io.IOException, &nbsp;&nbsp;&nbsp; javax.servlet.ServletException {
&nbsp;&nbsp;&nbsp; filterChain.doFilter(servletRequest, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; servletResponse);&nbsp; }
&nbsp; public javax.servlet.FilterConfig getFilterConfig() {&nbsp;&nbsp;&nbsp; return myFilterConfig; &nbsp; }&nbsp;&nbsp;&nbsp; &nbsp; public void &nbsp; setFilterConfig(javax.servlet.FilterConfig &nbsp;&nbsp;&nbsp; filterConfig) {&nbsp;&nbsp;&nbsp; myFilterConfig = filterConfig;&nbsp; }}
Template Filter StrategyUsando 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 templatepublic abstract class TemplateFilter implements &nbsp; javax.servlet.Filter {&nbsp; private FilterConfig filterConfig;
&nbsp; public void setFilterConfig(FilterConfig fc) { &nbsp;&nbsp;&nbsp; filterConfig=fc; &nbsp; }
&nbsp; public FilterConfig getFilterConfig()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { &nbsp;&nbsp;&nbsp; return filterConfig; &nbsp; }
&nbsp; public void doFilter(ServletRequest request, &nbsp;&nbsp;&nbsp; ServletResponse response, FilterChain chain)&nbsp;&nbsp;&nbsp; throws IOException, ServletException {&nbsp;&nbsp;&nbsp; // Common processing for all filters can go here &nbsp;&nbsp;&nbsp; doPreProcessing(request, response, chain);
&nbsp;&nbsp;&nbsp; // Common processing for all filters can go here&nbsp;&nbsp;&nbsp; doMainProcessing(request, response, chain);
&nbsp;&nbsp;&nbsp; // Common processing for all filters can go here &nbsp;&nbsp;&nbsp; doPostProcessing(request, response, chain);
&nbsp;&nbsp;&nbsp; // Common processing for all filters can go here
&nbsp;&nbsp;&nbsp; // Pass control to the next filter in the chain or &nbsp;&nbsp;&nbsp; // to the target resource&nbsp;&nbsp;&nbsp; chain.doFilter(request, response);&nbsp; }&nbsp; public void doPreProcessing(ServletRequest request,&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ServletResponse response, FilterChain chain) {&nbsp; }
&nbsp; public void doPostProcessing(ServletRequest request, &nbsp;&nbsp;&nbsp; ServletResponse response, FilterChain chain) {&nbsp; }
&nbsp; public abstract void doMainProcessing(ServletRequest &nbsp;&nbsp; request, ServletResponse response, FilterChain &nbsp;&nbsp; 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 {&nbsp; public void doPreProcessing(ServletRequest req, &nbsp;&nbsp;&nbsp; ServletResponse res, FilterChain chain) {&nbsp;&nbsp;&nbsp; //do some preprocessing here&nbsp; }
&nbsp; public void doMainProcessing(ServletRequest req, &nbsp;&nbsp;&nbsp; ServletResponse res, FilterChain chain) {&nbsp;&nbsp;&nbsp; //do the main processing;&nbsp; }}

﻿

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.&nbsp; 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ênciasCentraliza o controle de manipuladores acoplados de forma flexívelFiltros 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.
&nbsp;
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.
&nbsp;
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.
&nbsp;
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 relacionadosFront Controller
O controlador resolve alguns problemas semelhantes, mas é mais adequado ao tratamento de processamento central.
&nbsp;
Decorator [GoF]
O padrão Intercepting Filter está relacionado com o padrão Decorator, que prevê invólucros dinamicamente pluggable.
&nbsp;
Template Method [GoF]
O modelo padrão de método é usado para implementar o modelo de Filtro de estratégia.
&nbsp;
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.
&nbsp;
Tubos e filtros [POSA1]
O padrão Intercepting Filter está relacionado ao padrão de pipes e filtros.