拦截器

151 阅读4分钟
过滤器 Filter 应用场景 	统一编码处理、登录验证
 init:  初始化方法  destroy:   销毁方法
 *       doFilter: 方法拦截。 FilterChain他是一个接口  。  FilterConfig对象来获取
  拦截所有资源的配置是: /* 
       * @param request  请求对象 response  响应对象 chain    过滤器链对象 
     * @throws IOException  ServletException 
   package com.itheima.web.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException; 
 * 解决中文乱码的过滤器  配置过滤器的注解:  @WebFilter 
@WebFilter(urlPatterns = "/*",  //配置拦截的规则
            dispatcherTypes = DispatcherType.REQUEST,//配置拦截行为
            initParams = @WebInitParam(name = "encoding",value = "UTF-8")//配置初始化参数
            )
public class CharacterEncodingFilter implements Filter { 
    private FilterConfig filterConfig;
 //初始化方法    filterConfig ServletException 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }
  
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //使用过滤器的配置对象读取初始化参数
        String encoding = filterConfig.getInitParameter("encoding");
        //1.设置请求对象的字符集
        request.setCharacterEncoding(encoding);
        //2.设置响应对象的正文类型和字符集
        response.setContentType("text/html;charset="+encoding);
        //3.放行
        chain.doFilter(request,response);
    } 
    @Override
    public void destroy() {

    }
}   
* 在Filter中的url-pattern支持下面的匹配方式:
	1. 精确匹配:直接匹配到某个资源上
	2. 路径匹配:匹配某个目录,要求以/开头,以`*`结尾
	3. 后缀匹配:根据后缀匹配,要求以`*.`开头
         
 * 登录的Servlet 
@WebServlet("/login")
public class LoginServlet extends HttpServlet { 
    private static final String RIGHT_USERNAME = "泰斯特";
    private static final String RIGHT_PASSWORD = "1234"; 
    /**
     * 登录操作 * @param req resp ServletException IOException
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.解决乱码问题
        //req.setCharacterEncoding("UTF-8");
        //resp.setContentType("text/html;charset=UTF-8");
        //2.获取请求参数,用户名,密码和验证码
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String formCode = req.getParameter("code");
        //3.取出会话共享区域中存放的验证码
        HttpSession session = req.getSession();
        String sessionCode = (String)session.getAttribute("sessionCode");
        //4.判断验证码是否匹配
        if(!formCode.equals(sessionCode)){
            //把错误信息存入共享区域,并且跳转回登录页面
            req.setAttribute("errorMsg","验证码不匹配,请检查后重新输入");
            req.getRequestDispatcher("/login.jsp").forward(req,resp);
            return;
        }
        //5.用户名和密码的判断
        if(!RIGHT_USERNAME.equals(username)){
            //把错误信息存入共享区域,并且跳转回登录页面
            req.setAttribute("errorMsg","用户名或者密码不匹配,请检查后重新输入");
            req.getRequestDispatcher("/login.jsp").forward(req,resp);
            return;
        }
        if(!RIGHT_PASSWORD.equals(password)){
            //把错误信息存入共享区域,并且跳转回登录页面
            req.setAttribute("errorMsg","用户名或者密码不匹配,请检查后重新输入");
            req.getRequestDispatcher("/login.jsp").forward(req,resp);
            return;
        }
        //6.当代码走到此处,就表示验证码,用户名和密码都校验通过了,那么此时就应该是登录成功
        //当登录成功之后,我们应该删除验证码
        session.removeAttribute("sessionCode");
        //把登录成功的信息存入了
        session.setAttribute("loginSuccessName",username);
        resp.sendRedirect(req.getContextPath()+"/index.jsp");
    }
}
* 用于生成验证码的Servlet 
@WebServlet("/captcha")
public class CaptchaServlet extends HttpServlet { 
     * 生成验证码 req  resp ServletException
     * @throws IOException
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.创建生成验证码的对象
        LineCaptcha lineCaptcha = new LineCaptcha(200,30,4,10);
        //2.取出生成验证码
        String code = lineCaptcha.getCode();
        //3.把取到的验证码存入会话共享区域
        HttpSession session = req.getSession();
        session.setAttribute("sessionCode",code);
        //4.把验证码写到浏览器端
        lineCaptcha.write(resp.getOutputStream());
    }
}
 未登录状态下不能被访问-检查登录的过滤器 
@WebFilter("/*")
public class CheckLoginFilter implements Filter { 
    private FilterConfig filterConfig; 
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        //把和协议无关的请求和响应对象,转成和协议相关的
        HttpServletRequest  request;
        HttpServletResponse response;

        if (!(req instanceof HttpServletRequest &&
                res instanceof HttpServletResponse)) {
            throw new ServletException("non-HTTP request or response");
        }
        request = (HttpServletRequest) req;
        response = (HttpServletResponse) res;  
        //判断哪些资源可以不拦截,直接放行    首页面,登录页面,登录操作和获取验证码操作(/captcha) 
        //再把字符串数组转成list集合
        List<String>  pathArray = new ArrayList();
        pathList.add("/index.jsp");
        pathList.add("/");
        pathList.add("/login.jsp");
        pathList.add("/captcha");
        pathList.add("/login"); 
        
        
       //获取应用域对象
        ServletContext servletContext = filterConfig.getServletContext();
        //从应用域中获取不需要拦截的路径
        String[] pathArray  = (String[])servletContext.getAttribute("pathList");
        
        
        //取出当前访问的URI
        String uri = request.getRequestURI();
        System.out.println(uri); 
        //判断当前的uri是不是和pathList里的一致,一致就直接放行
        for(String path : pathArray){
            if(uri.equals(path)){
                //不需要判断是否已经登录了,那么就直接放行
                chain.doFilter(request,response);
                //后面的验证不用走了
                return;
            }
        } 
        //如果不是上面路径列表中的,就需要判断是否已经登录了
        HttpSession session = request.getSession();
        Object loginSuccessName = session.getAttribute("loginSuccessName");
        if(loginSuccessName == null){
            //没有登录,让他去登录
            response.getWriter().write("游客无权浏览,3秒后前往登录页面");
            response.setHeader("Refresh","3;URL=/login.jsp");
            return;
        } 
        //如果登录了,就放行
        chain.doFilter(request,response);
    }
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //给filterConfig赋值
        this.filterConfig = filterConfig;
    } 
    @Override
    public void destroy() { 
    }
}