一.新建过滤器
这里我以session登录校验为例写了一个过滤器的例子
1.先写一个通过用户名密码登录的小栗子(用户名、密码都是root)
@Controller
@RestController
public class LoginController {
@RequestMapping("login")
public String login(String name,String pwd,HttpServletRequest request) {
HttpSession session = request.getSession();
if(name.equals("root")&&pwd.equals("root")) {
User user = new User();
user.setName(name);
session.setAttribute("user",user);
return "登录成功";
} else {
return "用户名或密码错误!";
}
}
}
2.写登录校验的过滤器
1.新建一个SessionFilter 实现(implements)javax.servlet.Filter接口,并重写其中的方法
public class SessionFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
2.详细代码
public class SessionFilter implements Filter {
//标示符:表示当前用户未登录(可根据自己项目需要改为json样式)
String NO_LOGIN = "您还未登录";
//不需要登录就可以访问的路径(比如:注册登录等)
String[] includeUrls = new String[]{"/login","register"};
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpSession session = request.getSession(false);
String uri = request.getRequestURI();
System.out.println("filter url:"+uri);
//是否需要过滤
boolean needFilter = isNeedFilter(uri);
if (!needFilter) { //不需要过滤直接传给下一个过滤器
filterChain.doFilter(servletRequest, servletResponse);
} else { //需要过滤器
// session中包含user对象,则是登录状态
if(session!=null&&session.getAttribute("user") != null){
// System.out.println("user:"+session.getAttribute("user"));
filterChain.doFilter(request, response);
}else{
String requestType = request.getHeader("X-Requested-With");
//判断是否是ajax请求
if(requestType!=null && "XMLHttpRequest".equals(requestType)){
response.getWriter().write(this.NO_LOGIN);
}else{
//重定向到登录页(需要在static文件夹下建立此html文件)
response.sendRedirect(request.getContextPath()+"/user/login.html");
}
return;
}
}
}
/**
* @Author: xxxxx
* @Description: 是否需要过滤
* @Date: 2018-03-12 13:20:54
* @param uri
*/
public boolean isNeedFilter(String uri) {
for (String includeUrl : includeUrls) {
if(includeUrl.equals(uri)) {
return false;
}
}
return true;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
3.过滤器的配置
过滤器的配置有2种方式,第一种是纯注解的方式,第二种是写过滤器注册配置类
1.通过注解方式配置过滤器
- 在过滤器上添加WebFilter注解
- 在启动类添加ServletComponentScan注解
@WebFilter(filterName = "sessionFilter",urlPatterns = {"/*"})
public class SessionFilter implements Filter {
@SpringBootApplication
@ServletComponentScan
public class FileUploadApplication {
public static void main(String[] args) {
SpringApplication.run(FileUploadApplication.class, args);
}
}
2.通过过滤器注册配置类使用过滤器
@Configuration
public class WebComponent2Config {
@Bean
public FilterRegistrationBean someFilterRegistration1() {
//新建过滤器注册类
FilterRegistrationBean registration = new FilterRegistrationBean();
// 添加我们写好的过滤器
registration.setFilter( new SessionFilter());
// 设置过滤器的URL模式
registration.addUrlPatterns("/*");
return registration;
}
}
4.测试一下
1.不登录,访问other(localhost/user/other.html)
回车
因为没有登录所以重定向到了登录页
2.登录
http://localhost/login?name=root&pwd=root
3.再访问other(localhost/user/other.html)
这次是登录状态,所以过滤器放行,能成功进入other
5.拓展
当有多个过滤器需要按顺序执行时怎么办?
使用注解的配置方法不能配置顺序,但是可以通过过滤器名字的字典顺序实现顺序过滤(比如AFilter就会在BFilter前执行),显然这种方法看起来不怎么正经。
但是我们可以使用第二种配置方法.
通过给注册类设置order,order越小,执行优先级越高
@Bean
public FilterRegistrationBean someFilterRegistration1() {
//新建过滤器注册类
FilterRegistrationBean registration = new FilterRegistrationBean();
// 添加我们写好的过滤器
registration.setFilter( new SessionFilter());
// 设置过滤器的URL模式
registration.addUrlPatterns("/*");
//设置过滤器顺序
registration.setOrder(1);
return registration;
}