leftso 5821 0 2017-11-11 13:03:39

文章位置:左搜> 编程技术> 正文

引言

    在Java编程中,web项目通常会使用一些filter处理一些特定的业务。这里主要讲解springboot中filter的几种配置和使用。

一.创建一个spring boot 项目

创建spring boot项目的方法这里就不详细介绍了,不清楚的可以参考:spring boot 入门项目创建
下面是一个创建好的项目结构图:
项目结构图
其中主要的在于上面的config目录下的FilterConfig.java和下面的filter中两个filter的实现类。

二.Filter的实现类

这里的filter指的是javax.servlet.Filter;接口。在spring boot框架中有很多方式来实现Filter接口。下面就讲常用的两种。

2.1javax.servlet.Filter;原生接口的实现

MyFilter.java:
package net.xqlee.project.filter;

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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 测试用filter
 * 
 * @author xqlee
 *
 */
public class MyFilter implements Filter {

	private static final Logger log = LoggerFactory.getLogger(MyFilter.class);

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		log.info("MyFilter 初始化中...");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		log.info("进入 MyFilter");
		chain.doFilter(request, response);
	}

	@Override
	public void destroy() {
		log.info("MyFilter 销毁中...");
	}

}
上面的代码就是一个简单的Filter接口实现类.其中需要处理的业务一般放在doFilter方法中。

2.2继承spring的OncePerRequestFilter来实现Filter

package net.xqlee.project.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.filter.OncePerRequestFilter;

/**
 * 通过继承spring提供的filter来实现filter
 * 
 * @author xqlee
 *
 */
public class MyOncePerRequestFilter extends OncePerRequestFilter {

	private static final Logger log = LoggerFactory.getLogger(MyOncePerRequestFilter.class);

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		log.info("进入 MyOncePerRequestFilter");
		filterChain.doFilter(request, response);
	}

}
说明:Spring 的OncePerRequestFilter类实际上是一个实现了Filter接口的抽象类。spring对Filter进行了一些封装处理。

三.配置Filter到容器中

    上面只是创建好了两个Filter实现类。在web编程中我们知道需要在web.xml中配置相应的过滤器内容,如过滤的url,过滤器名字,参数等。spring boot框架中为配置Filter进行了一些封装使得我们可以用spring风格的方式配置Filter。
首先创建一个类,添加配置注解,并将上面的两个过滤器配置到这个配置类中:
package net.xqlee.project.config;

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

import net.xqlee.project.filter.MyFilter;
import net.xqlee.project.filter.MyOncePerRequestFilter;

/**
 * 配置拦截器
 * 
 * @author xqlee
 *
 */
@Configuration
public class FilterConfig {
	/**
	 * 拦截器注册
	 * 
	 * @return
	 */
	@Bean
	public FilterRegistrationBean myFilterRegistration() {
		FilterRegistrationBean registration = new FilterRegistrationBean();
		registration.setFilter(new MyFilter());
		registration.addUrlPatterns("/a/*");// 拦截路径
		registration.setName("MyFilter");// 拦截器名称
		registration.setOrder(1);// 顺序
		return registration;
	}

	/**
	 * 拦截器注册
	 * 
	 * @return
	 */
	@Bean
	public FilterRegistrationBean myOncePerRequestFilterRegistration() {
		FilterRegistrationBean registration = new FilterRegistrationBean();
		registration.setFilter(new MyOncePerRequestFilter());
		registration.addUrlPatterns("/*");// 拦截路径
		registration.setName("MyOncePerRequestFilter");// 拦截器名称
		registration.setOrder(2);// 顺序
		return registration;
	}

}

四.Spring boot Filter测试

启动spring boot项目,观察启动日志:
注意观察上图中红色圈出来的地方,我们可以看到两个filter都进行了初始化并且也显示出来了过滤器的过滤地址。

为了进一步的测试其是否作用,创建一个简单的controller进行测试
package net.xqlee.project.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

	@GetMapping("/a/filter.do")
	public Object hello() {
		return "Hello Filter";
	}

	@GetMapping("/")
	public Object index() {
		return "Welcome Index";
	}

}

浏览器访问地址http://localhost:8080/
index
观察eclipse控制台日志:
访问日志
我们可以看到只有MyOncePerRequestFilter的日志,因为从启动日志图中可以看到MyOncePerRequestFilter的过滤路径是所有,而myfilter过滤路径是/a/,所以这里只能看到MyOncePerRequestFilter的日志。

接下来访问地址:http://localhost:8080/a/filter.do
访问
后端日志:
这次可以看到两个过滤器的日志了。同时也说明配置的过滤器已经生效。