深入理解Java中Filter的作用种类及应用场景

Java
266
0
0
2023-05-18
目录
  • 如何使用Filter
  • Filter的生命周期
  • Filter执行顺序
  • Filter细节
  • 自动登录
  • BeanUtils的使用
  • 总结

如何使用Filter

在Java Web应用程序中,使用Filter非常简单,只需编写一个类实现javax.servlet.Filter接口,然后在web.xml配置文件中配置Filter,即可使用Filter。下面是一个Filter的代码示例:

public class MyFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化操作
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 过滤器逻辑处理
        chain.doFilter(request, response);
    }
    public void destroy() {
        // 销毁操作
    }
}

在web.xml配置文件中配置Filter:

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.example.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

上述代码中的<filter>标签指定了Filter的名称和类路径,<filter-mapping>标签指定了Filter的映射规则,即该Filter拦截哪些URL。

Filter的生命周期

Filter的生命周期共有三个方法:init()、doFilter()和destroy()。

init()方法:在Filter被创建时调用,用于初始化Filter。该方法只会被调用一次。

doFilter()方法:在每个请求被拦截时调用,用于处理请求和响应。如果需要继续执行下一个Filter,则需要调用chain.doFilter(request, response)方法,否则不需要调用该方法。

destroy()方法:在Filter被销毁时调用,用于释放资源。

Filter执行顺序

在web.xml配置文件中,可以配置多个Filter,它们的执行顺序是按照在配置文件中定义的顺序依次执行的。例如:

<filter>
    <filter-name>FilterA</filter-name>
    <filter-class>com.example.FilterA</filter-class>
</filter>
<filter-mapping>
    <filter-name>FilterA</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
    <filter-name>FilterB</filter-name>
    <filter-class>com.example.FilterB</filter-class>
</filter>
<filter-mapping>
    <filter-name>FilterB</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

在上述配置中,FilterA会先执行,然后才会执行FilterB。

Filter细节

自动登录

在Web应用程序中,通常需要实现自动登录功能,即用户在登录成功后,下次访问时不需要再次输入用户名和密码,直接访问即可。下面是一个简单的自动登录的思路:

  • 用户登录时,将用户名和密码保存在Cookie中。
  • 在Filter中判断用户是否已经登录,如果没有登录,则判断是否存在Cookie,如果存在Cookie,则将Cookie中的用户名和密码自动填充到登录表单中,再次进行登录验证。

下面是一个简单的登录Servlet的代码示例:

public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 验证用户名和密码
        if ("admin".equals(username) && "123456".equals(password)) {
            // 登录成功,保存用户信息到Session中
            HttpSession session = request.getSession();
            session.setAttribute("username", username);
            // 保存自动登录信息到Cookie中
            Cookie cookie = new Cookie("autologin", username + ":" + password);
            cookie.setMaxAge(7 * 24 * 60 * 60); // 设置Cookie过期时间为一周
            response.addCookie(cookie);
            // 跳转到首页
            response.sendRedirect(request.getContextPath() + "/index.jsp");
        } else {
            // 登录失败,返回登录页面
            response.sendRedirect(request.getContextPath() + "/login.jsp");
        }
    }
}

下面是一个简单的自动登录Filter的代码示例:

public class AutoLoginFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化操作
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 判断用户是否已经登录
        HttpSession session = ((HttpServletRequest) request).getSession();
        String username = (String) session.getAttribute("username");
        if (username == null) {
            // 判断是否存在Cookie
            Cookie[] cookies = ((HttpServletRequest) request).getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if ("autologin".equals(cookie.getName())) {
                        // 自动填充用户名和密码
                        String[] values = cookie.getValue().split(":");
                        String autologinUsername = values[0];
                        String autologinPassword = values[1];
                        request.setAttribute("autologinUsername", autologinUsername);
                        request.setAttribute("autologinPassword", autologinPassword);
                    }
                }
            }
        }
        chain.doFilter(request, response);
    }
    public void destroy() {
        // 销毁操作
    }
}

BeanUtils的使用

在Web开发中,经常需要将表单数据封装成JavaBean对象,这时可以使用BeanUtils工具类。BeanUtils可以将表单数据自动封装成JavaBean对象,简化了表单数据的处理。下面是一个BeanUtils的使用示例:

public class UserServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取表单数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        int age = Integer.parseInt(request.getParameter("age"));
        // 将数据封装成User对象
        User user = new User();
        try {
            BeanUtils.setProperty(user, "username", username);
            BeanUtils.setProperty(user, "password", password);
            BeanUtils.setProperty(user, "age", age);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 保存用户信息
        UserService userService = new UserService();
        userService.saveUser(user);
        // 跳转到用户列表页面
        response.sendRedirect(request.getContextPath() + "/user/list.jsp");
    }
}

上述代码中,通过BeanUtils.setProperty()方法将表单数据封装成User对象。

总结

Filter是Java Web中非常重要的组件,可以对请求和响应进行拦截处理,实现许多功能。在使用Filter时,需要注意Filter的生命周期、执行顺序和一些细节问题。同时,在Web开发中,BeanUtils工具类可以简化表单数据的处理,提高开发效率。

除了上述的示例代码,Filter还可以实现更多的功能,如:字符集过滤、XSS攻击防范、文件上传、数据加密等等。在实际开发中,可以根据具体需求编写自己的Filter。