Excluindo URLs para um filtro em um aplicativo Web Spring

Excluindo URLs para um filtro em um aplicativo Web Spring

1. Visão geral

A maioria dos aplicativos da Web tem um caso de uso de executar operações como log de solicitação, validação ou autenticação. E, o que é mais, comotasks are usually shared across a set of HTTP endpoints.

A boa notícia é que o framework da web Spring fornece umfiltering mechanism exatamente para esse propósito.

Neste tutorial, aprenderemos como afilter-style task can be included or excluded from execution for a given set of URLs.

2. Filtrar URLs específicos

Digamos que nosso aplicativo da web precise registrar algumas informações sobre suas solicitações, como seus caminhos e tipos de conteúdo. Uma maneira de fazer isso é criando um filtro de log.

2.1. Filtro de registro

Primeiro, vamos criar nosso filtro de registro em uma classeLogFilter que estende o OncePerRequestFilter class and implements the doFilterInternal method:

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
  FilterChain filterChain) throws ServletException, IOException {
    String path = request.getRequestURI();
    String contentType = request.getContentType();
    logger.info("Request URL path : {}, Request content type: {}", path, contentType);
    filterChain.doFilter(request, response);
}

2.1. Filtro de entrada de regra

Vamos supor que precisamos que a tarefa de registro seja executada apenas para padrões de URL selecionados, a saber/health,/faq/*.. Para isso, vamos registrar nosso filtro de registro usando umFilterRegistrationBean de modo que corresponda apenas os padrões de URL necessários:

@Bean
public FilterRegistrationBean logFilter() {
    FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
    registrationBean.setFilter(new LogFilter());
    registrationBean.addUrlPatterns("/health","/faq/*");
    return registrationBean;
}

2.2. Filtro de exclusão

Se queremos excluir URLs da execução da tarefa de log, podemos conseguir isso facilmente de duas maneiras:

  • Para um novo URL, certifique-se de que ele não corresponda aos padrões de URL usados ​​pelo filtro

  • Para um URL antigo para o qual o logon foi ativado anteriormente, podemos modificar o padrão de URL para excluir este URL

3. Filtrar todos os URLs possíveis

Conhecemos facilmente nosso caso de uso anterior de incluir URLs emLogFilter com o mínimo de esforço. No entanto, obtémtrickier if the Filter uses a wildcard () para corresponder a todos os padrões de URL possíveis. *

Nessa circunstância, precisaremos escrever a lógica de inclusão e exclusão nós mesmos.

3.1. Filter personalizado

Os clientes podem enviar informações úteis para o servidor usando os cabeçalhos de solicitação. Digamos que nosso aplicativo da web esteja atualmente operacional apenas nos Estados Unidos, o que significa que não queremos processar as solicitações provenientes de outros países.

Vamos imaginar ainda que nosso aplicativo da web indique a localidade por meio de um cabeçalho de solicitaçãoX-Country-Code. Consequentemente, cada solicitação vem com essas informações, e temos um argumento claro para o uso de um filtro.

Vamos implementar umFilter que verifica o cabeçalho, rejeitando solicitações que não atendem às nossas condições:

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
      FilterChain filterChain) throws ServletException, IOException {

    String countryCode = request.getHeader("X-Country-Code");
    if (!"US".equals(countryCode)) {
        response.sendError(HttpStatus.BAD_REQUEST.value(), "Invalid Locale");
        return;
    }

    filterChain.doFilter(request, response);
}

3.2. Filter Registro

Para começar, vamos usar asterisk (*) wildcard to register our filter para combinar todos os padrões de URL possíveis:

@Bean
public FilterRegistrationBean headerValidatorFilter() {
    FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
    registrationBean.setFilter(new HeaderValidatorFilter());
    registrationBean.addUrlPatterns("*");
    return registrationBean;
}

Em um momento posterior, podemos excluir os padrões de URL que não são necessários para executar a tarefa de validar as informações do cabeçalho da solicitação de localidade.

3.3. Exclusão de URL

Vamos imaginar novamente que temos uma rota da web em/health que pode ser usada para fazer uma verificação de integridade do aplicativo em pingue-pongue.

Até o momento, todas as solicitações acionarão nosso filtro. Como podemos imaginar, é uma sobrecarga quando se trata de nossa verificação de saúde.

Então, vamos simplificar nossas solicitações/health, excluindo-o do corpo principal do nosso filtro:

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
      throws ServletException, IOException {
    String path = request.getRequestURI();
    if ("/health".equals(path)) {
        filterChain.doFilter(request, response);
        return;
    }

    String countryCode = request.getHeader("X-Country-Code");
    // ... same as before
}

We must note that adding this custom logic within the doFilter method introduces coupling between the /health endpoint and our filter. Como tal, não é o ideal, pois poderíamos quebrar a lógica de filtragem se alterarmos o endpoint de verificação de integridade sem fazer uma alteração correspondente dentro do métododoFilter.

4. Conclusão

Neste tutorial, exploramos como excluir padrão (s) de URL de um filtro de servlet em um aplicativo da web Spring Boot para dois casos de uso, ou seja, registro e validação de cabeçalho de solicitação.

Além disso, aprendemos quegets tricky to rule-out a specific set of URLs for a filter that uses a * wildcard for matching all possible URL patterns.

Como sempre, o código-fonte completo do tutorial está disponívelover on GitHub.