6、Spring Boot:自定义Servlet Filters

在项目中使用filters可以进行访问权限验证、过滤有XSS威胁的字符、记录访问日志等等。Spring Boot默认在项目中添加了两个Filter:OrderedCharacterEncodingFilter和HiddenHttpMethodFilter。并且也可以自定义Filter。

 

自定义Servlet Filters现在有两种方法。

 

老方法自定义Filter步骤:

  • 自定义一个类,并实现javax.servlet.Filter接口
  • 通过FilterRegistrationBean类把自定义Filter添加到Servlet 3.0+容器中

 

代码:

package com.example.demo.config;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WebConfiguration
{
    @Bean
    public FilterRegistrationBean<TestFilter> testFilterRegistration()
    {
         // 通过FilterRegistrationBean类把自定义Filter添加到Servlet 3.0+容器中
         FilterRegistrationBean<TestFilter> registration = new FilterRegistrationBean<TestFilter>();
         registration.setFilter(new TestFilter()); // 设置自定义Filter
         registration.addUrlPatterns("/*"); // 设置匹配规则
         registration.addInitParameter("paramName", "paramValue"); // 在这里给自定义Filter传递初始化参数
         registration.setName("TestFilter"); // 设置注册名称,如果不设置此项,则默认以自定义Filter类的名称做为注册名称
         registration.setOrder(1); // 设置过滤优先级,值越小,越先执行
         return registration;
    }
    
    // 自定义Filter
    public class TestFilter implements Filter
    {
         @Override
         public void init(FilterConfig filterConfig) throws ServletException
         {
             // TODO Auto-generated method stub
             Filter.super.init(filterConfig);

             // 在这里可以获取到FilterRegistrationBean里addInitParameter里设置的参数
             System.out.println(filterConfig.getInitParameter("paramName"));
         }
        
         @Override
         public void doFilter(ServletRequest sRequest, ServletResponse sResponse, FilterChain fChain) throws IOException, ServletException
         {
             // TODO Auto-generated method stub
             HttpServletRequest request = (HttpServletRequest) sRequest;
             
             // 获取并打印出过滤到的RequestURI
             System.out.println("TestFilter URL:" + request.getRequestURI());
             
             // 最后要把请求加入到过滤链中
             fChain.doFilter(sRequest, sResponse);
         }
        
    }
}

 

启动Spring Boot项目,会看到控制台打印日志中显示:

Mapping filter: 'TestFilter' to urls: [/*]

paramValue

 

在浏览器中输入http://localhost:8080/hello,可以看到控制台打印出来过滤到的访问信息:

 

新方法自定义Filter步骤:

1、自定义一个类,并实现javax.servlet.Filter接口

package com.example.demo.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;

import org.springframework.core.annotation.Order;

@Order(1) // 设置过滤优先级,值越小,越先执行(目前测试这个功能无效)
@WebFilter(filterName="testFilterNew", urlPatterns= {"/*"}, initParams={@WebInitParam(name="paramNameNew", value="paramValueNew")}) // 设置注册名称、匹配规则、初始化参数
public class TestFilterNew implements Filter
{
     @Override
     public void init(FilterConfig filterConfig) throws ServletException
     {
         // TODO Auto-generated method stub
         Filter.super.init(filterConfig);
         
         System.out.println(filterConfig.getInitParameter("paramNameNew"));
     }
     
     @Override
     public void doFilter(ServletRequest sRequest, ServletResponse sResponse, FilterChain fChain) throws IOException, ServletException
     {
         // TODO Auto-generated method stub
         HttpServletRequest request = (HttpServletRequest) sRequest;
         
         // 获取并打印出过滤到的RequestURI
         System.out.println("TestFilterNew URL:" + request.getRequestURI());
         
         // 最后要把请求加入到过滤链中
         fChain.doFilter(sRequest, sResponse);
     }

}

 

2、在Spring Boot启动类中加入@ServletComponentScan

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan // 扫描Servlet组件
public class DemoApplication 
{
     public static void main(String[] args) 
     {
         SpringApplication.run(DemoApplication.class, args);
     }
}

在 SpringBootApplication 上使用@ServletComponentScan 注解后,Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。

 

3、启动Spring Boot项目,会看到控制台打印日志中显示:

Mapping filter: 'testFilterNew' to urls: [/*]

paramValueNew

 

4、在浏览器中输入http://localhost:8080/hello,可以看到控制台打印出来过滤到的访问信息:

 

补充:

对于@Order无效的问题

  • 通过FilterRegistrationBean的setOrder方法可以实现顺序。
  • 经过测试发现,自定义Filter类的class类名的字典正序就是@Order注解加载后的实际执行顺序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值