书籍封面

JavaWEB-5

作者 佚名
15.0 分钟

摘要

Filter 与文件上传下载总结

  • Filter 可以拦截请求和响应,修改或处理客户端和服务端之间交换的数据。文件上传需要 JSP 设置 input 类型、form 表单方法和编码类型,Servlet 使用 fileupload 组件处理。
  • 通过学习本节,你可以掌握如何使用 Filter 拦截和处理请求,以及如何实现文件的上传功能,为你的 Web 应用增加更多灵活性和实用性。

核心内容:

1. Filter 的基本使用:

  • Filter 用于拦截传入的请求和传出的响应,并修改或处理数据流。
    • 实现:自定义类实现 Filter 接口,并在 web.xml 或使用注解进行配置。
    • doFilter 方法是 Filter 的核心,处理业务逻辑后必须调用 filterChain.doFilter(servletRequest, servletResponse) 将请求向后传递。
    • 实例:
      • 统一处理中文乱码:设置请求的字符编码为 UTF-8。
      • 屏蔽敏感词:替换请求参数中的敏感词。
      • 控制资源访问权限:检查用户是否已登录,未登录则重定向到登录页面。
    • 行动建议:在开发 Web 应用时,合理使用 Filter 可以有效地进行请求预处理和响应后处理,提高代码的模块化和可维护性。

2. Filter 的生命周期:

  • Filter 的生命周期由 Tomcat 容器管理,包括实例化、初始化、执行过滤和销毁。
    • Tomcat 启动时,通过反射调用 Filter 的无参构造函数创建实例,并调用 init 方法进行初始化。
    • 每次请求经过 Filter 时,doFilter 方法会被调用。
    • Tomcat 关闭时,调用 destroy 方法销毁 Filter 对象。
    • 多个 Filter 的调用顺序由 web.xml 中的配置顺序决定,或者根据注解的定义顺序。
    • 实例:
      • 无参构造函数:只调用一次,在 Tomcat 启动时创建 Filter 实例。
      • init 方法:只调用一次,在 Filter 实例化后进行初始化操作。
      • doFilter 方法:调用多次,每次请求匹配 Filter 的 URL 模式时都会执行。
      • destroy 方法:只调用一次,在 Tomcat 关闭时销毁 Filter 实例,释放资源。
    • 行动建议:了解 Filter 的生命周期有助于更好地管理 Filter 的资源,避免内存泄漏等问题。

3. 文件上传:

  • 文件上传功能需要前端 JSP 页面和后端 Servlet 协同完成。
    • 前端 JSP 页面:
      • <input> 标签的 type 属性设置为 file,用于选择文件。
      • <form> 标签的 method 属性设置为 post
      • <form> 标签的 enctype 属性设置为 multipart/form-data,以二进制形式传输数据。
    • 后端 Servlet:
      • 使用 Apache Commons FileUpload 组件处理文件上传。
      • 通过 DiskFileItemFactoryServletFileUpload 解析请求,获取 FileItem 对象列表。
      • 遍历 FileItem 对象,区分普通表单字段和文件字段。
      • 对于文件字段,获取文件名、大小和输入流,将文件保存到服务器。
    • 实例:
      • 前端 JSP 页面:
        <form action="/upload" method="post" enctype="multipart/form-data">
            <input type="file" name="file">
            <input type="submit" value="上传">
        </form>
        
      • 后端 Servlet:
        DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
        ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
        List<FileItem> list = servletFileUpload.parseRequest(req);
        for (FileItem fileItem : list) {
            if (!fileItem.isFormField()) {
                String fileName = fileItem.getName();
                InputStream inputStream = fileItem.getInputStream();
                String path = req.getServletContext().getRealPath("file/" + fileName);
                OutputStream outputStream = new FileOutputStream(path);
                int temp = 0;
                while ((temp = inputStream.read()) != -1) {
                    outputStream.write(temp);
                }
                outputStream.close();
                inputStream.close();
            }
        }
        
    • 行动建议:在实现文件上传功能时,注意处理异常情况,例如文件大小超过限制、上传失败等。

问答

Q: Filter 如何处理中文乱码问题?

A: Filter 可以通过设置 ServletRequest 的字符编码为 UTF-8 来统一处理中文乱码。例如:

public class CharacterFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("UTF-8");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

Q: 如何在 Filter 中控制资源的访问权限?

A: Filter 可以通过检查用户的登录状态来控制资源的访问权限。例如,检查 HttpSession 中是否存在用户信息,如果不存在则重定向到登录页面。

public class DownloadFilter implements Filter {
    @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();
        String name = (String) session.getAttribute("name");
        if (name == null) {
            response.sendRedirect("/login.jsp");
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
}

Q: 文件上传时,enctype="multipart/form-data" 的作用是什么?

A: enctype="multipart/form-data" 用于指定表单数据以多部分形式进行编码,以便能够传输文件数据。这种编码方式将表单数据分成多个部分,每个部分包含一个字段的数据,其中文件数据以二进制流的形式传输。

Q: 如何使用 Apache Commons FileUpload 组件处理文件上传?

A: 使用 Apache Commons FileUpload 组件处理文件上传的步骤如下:

  1. 创建 DiskFileItemFactory 对象,用于配置磁盘存储。
  2. 创建 ServletFileUpload 对象,并传入 DiskFileItemFactory 对象。
  3. 调用 ServletFileUploadparseRequest 方法解析请求,获取 FileItem 对象列表。
  4. 遍历 FileItem 对象,区分普通表单字段和文件字段。
  5. 对于文件字段,获取文件名、大小和输入流,将文件保存到服务器。

思维导图

目标读者

本文档适合Java Web初学者、Java Web开发工程师以及需要了解Filter和文件上传下载的开发人员。读者应具备一定的Java基础知识和Web开发经验,了解Servlet、JSP等基本概念。

作者背景

该文档未提供作者的详细背景信息,通常Java Web相关的文档作者应具备Java开发经验,熟悉Servlet、JSP等技术,并对Web应用架构有一定了解。可能是一位经验丰富的Java Web开发工程师或教师。

历史背景

在早期的Java Web开发中,Servlet是处理HTTP请求的主要组件。随着Web应用复杂度的增加,需要在请求到达Servlet之前或响应返回客户端之后进行一些预处理或后处理操作,例如字符编码转换、安全检查、日志记录等。Filter应运而生,它提供了一种声明式的方式来拦截和处理HTTP请求和响应,无需修改Servlet的代码,实现了AOP(面向切面编程)的思想,提高了代码的复用性和可维护性。

章节摘要

音频

Comming Soon...