在日常的Web开发中,我们经常会使用到过滤器去过滤一些东西,我们知道,SpringMVC的模式下,过滤器只要定义在Web.xml文件中即可(不做过多演示)。
那在Springboot中,Filter如何使用呢?
下面写一个简单的例子去理解Filter在Springboot中的使用:
要想使用filter,需要写一个方法继承Filter类,我们写如下两个自己的Filter类,首先是FirstFilter类,其中@Order里边的数字越小代表越先被该Filter过滤,@WebFilter代表这是个Filter类并把这个类注入到容器中:
package com.buxiaoxia.business.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 javax.servlet.annotation.WebFilter;
import org.springframework.core.annotation.Order;
@Order(1)
@WebFilter(filterName = "firstFilter", urlPatterns = "/*")
public class Firstfilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void destroy() {
Filter.super.destroy();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("First filter before");
chain.doFilter(request, response);
System.out.println("First filter after");
}
}
然后是第二个Filter,SecondFilter类:
package com.buxiaoxia.business.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 javax.servlet.annotation.WebFilter;
import org.springframework.core.annotation.Order;
@Order(2)
@WebFilter(filterName = "secondFilter", urlPatterns = "/*")
public class SecondFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void destroy() {
Filter.super.destroy();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("second filter before");
chain.doFilter(request, response);
System.out.println("second filter after");
}
}
然后我们把Controller类也写出来吧:
package com.buxiaoxia.business.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v1")
public class FilterController {
@GetMapping("/filter/test")
public String test1() {
System.out.println("method in controller");
return "test1";
}
}
最后是springboot的主方法入口,注意,由于我们使用注解注入的Filter,所以要在下边这个Application类中加入@ServletComponentScan注解:
package com.buxiaoxia;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
/**
* Created by xw on 2017/2/20.
* 2017-02-20 16:51
*/
/**
* @author kevliu
*
*/
@SpringBootApplication
@ServletComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
首先我们先来看一下执行结果,启动后访问127.0.0.1:8080/test1,在后台中打印如下信息:
我们可以看出代码执行的流程,首先请求被firstfilter截获,打印出first filter 1,然后去执行chain.doFilter(request, response),这句话代表着请求会转发给过滤器链上下一个对象,也就是secondfilter,所以打印出secondfilter里的second filter 1,接下来再执行secondfilter里的chain.dofilter()方法,请求再转发给下一个对象,由于没有其他的filter了,所以会转发给controller,打印出了controller类中的method in controller,接下来再去内存栈里调用secondfilter的print("second filter 2"),然后再去内存栈里调用firstfilter的print("first filter 1")。所以如果在自己实现的Filter类的doFilter方法里不加chain.doFilter(req, rep)是万万不行的,那样会导致请求到了这个filter里就不再往下走了,永远进不了controller中。
至此,我们的Filter就完成了。