Filter过滤器
**作用:**拦截请求
当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。
其实可以这样理解,当用户请求某个Servlet时,Tomcat会去执行注册在这个请求上的Filter,然后是否“放行”由Filter来决定。可以理解为,Filter来决定是否能调用Servlet!当执行完成Servlet的代码后,还会执行Filter后面的代码。
使用过滤器
- 编写一个类实现javax.servlet.Filter接口
- 在web.xml文件或使用注解对过滤器进行配置, 配置该过滤器拦截哪些请求的url
FilterChain 过滤器链
doFilter()方法的参数中有一个类型为FilterChain的参数,它只有一个方法:doFilter(ServletRequest,ServletResponse)
。
前面我们说doFilter()方法的放行,让请求流访问目标资源!但这么说不严密,其实调用该方法的意思是,“我(当前Filter)”放行了,但不代表其他人(其他过滤器)也放行。
也就是说,一个目标资源上,可能部署了多个过滤器,就好比在你去北京的路上有多个打劫的匪人(过滤器),而其中第一伙匪人放行了,但不代表第二伙匪人也放行了,所以调用FilterChain类的doFilter()方法表示的是执行下一个过滤器的doFilter()方法,或者是执行目标资源!
如果当前过滤器是最后一个过滤器,那么调用chain.doFilter()方法表示执行目标资源,如果不是最后一个过滤器,那么chain.doFilter()表示执行下一个过滤器的doFilter()方法。
放行
filterChain.doFilter(servletRequest,servletResponse);
如果Filter没有显示调用上面这一行代码,表示该过滤器不放行
过滤器的执行顺序:
使用web.xml配置文件配置过滤器: 过滤器的配置文件决定过滤器执行顺序
由过滤器的<filter-mapper>
顺序决定的, 谁的<filter-mapper>
在前,谁先执行
在web3.0提供注解@WebFilter的配置方式:
使用注解的方式, 过滤器执行的顺序, 由过滤器的名字决定,排在前面的先执行。 当有多个过滤器时, 推荐使用web.xml配置
访问控制
有些资源,必须登录了才能访问 例如:增删改必须登录才能访问
案例 未登录时访问拦截
被拦截的url执行过滤器的doFilter方法
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
// 1.判断是否已经登录
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
HttpSession session = request.getSession();
if(session.getAttribute("admin")!=null){
// 已登录,放行
chain.doFilter(req, resp);
return;//不执行后续方法内代码
}
// 2.未登录,拦截,跳转到登录界面
String requestURI = request.getRequestURI();//用户想要访问的资源
session.setAttribute("requestPage",requestURI);
response.sendRedirect(request.getContextPath()+"/login.jsp");
}
注意点:
- ServletRequest的对象req没有request.getSession()方法,所以要将对象转换成它的子类HttpServletRequest
2.判断是否放行的依据是用户是否已经登录,所以LoginServlet处理时若登录成功要将登录用户保存到域里作为依据
3.若放行,注意方法后的代码不要执行了(使用return 或else语句)
4.如果用户未登录,拦截跳转到登录界面,这里需要注意,若用户登录成功,应该跳转到用户想要访问的资源而不是首页(不要写死登录成功后跳转的界面)
- 用户想要访问资源被拦截时,保存用户想要访问的资源到域里( request.getRequestURI()),登录成功后跳转到保存的这个资源
LoginServlet处理用户登录请求
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.设置编码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html,charset=utf-8");
String error ="";
HttpSession session = request.getSession();
// 2.获取数据
String username = request.getParameter("username");
String psaaword = request.getParameter("password");
// 3.调用service
AdminService adminService = BeanFactory.creatBean(AdminService.class);