服务器测评网
我们一直在努力

Java如何获取上传文件的原始文件名?

获取上传文件名的基本方法

在Java开发中,处理文件上传是一项常见需求,而获取上传文件的原始名称是其中的关键步骤,无论是通过Web表单接收文件,还是通过API接口处理文件流,正确获取文件名都是后续业务逻辑(如文件存储、重命名、类型校验等)的基础,本文将系统介绍Java中获取上传文件名的多种方法,涵盖传统Servlet方式、Spring框架封装以及第三方库的使用,并附上注意事项和最佳实践。

Java如何获取上传文件的原始文件名?

基于Servlet 3.0+的原生方式

在未使用高级框架的情况下,Servlet 3.0及以上版本提供了对文件上传的原生支持,通过Part接口,可以方便地获取上传文件的相关信息,包括文件名。

前端表单配置

前端表单需设置enctype="multipart/form-data",这是文件上传的必要条件。

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file" />
    <button type="submit">上传</button>
</form>

后端获取文件名

在Servlet中,通过request.getPart("file")获取Part对象,再调用getSubmittedFileName()方法即可获取原始文件名,代码示例如下:

protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
    // 获取上传的Part对象
    Part part = request.getPart("file");
    // 获取原始文件名
    String fileName = part.getSubmittedFileName();
    System.out.println("原始文件名:" + fileName);
    // 进一步处理文件(如保存到服务器)
    String savePath = "/path/to/save/";
    part.write(savePath + fileName);
}

说明getSubmittedFileName()是Servlet 3.0新增的方法,直接返回客户端提交的文件名,无需手动解析Content-Disposition头,若使用旧版本Servlet,需通过解析请求头获取文件名,

String contentDisp = part.getHeader("Content-Disposition");
String fileName = contentDisp.substring(
    contentDisp.indexOf("filename=\"") + 10, 
    contentDisp.lastIndexOf("\"")
);

Spring框架中的文件名获取

Spring框架对文件上传进行了高度封装,提供了MultipartFile接口,简化了文件处理流程,无论是Spring MVC还是Spring Boot,均可通过MultipartFile轻松获取文件名。

Spring MVC传统方式

在Spring MVC中,通过@RequestParam注解将上传文件绑定到MultipartFile对象,再调用getOriginalFilename()方法获取文件名,控制器示例如下:

@Controller
public class FileUploadController {
    @PostMapping("/upload")
    public String handleUpload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return "上传失败:文件为空";
        }
        // 获取原始文件名
        String fileName = file.getOriginalFilename();
        System.out.println("原始文件名:" + fileName);
        // 获取文件大小(单位:字节)
        long size = file.getSize();
        System.out.println("文件大小:" + size + " bytes");
        // 获取文件类型(MIME类型)
        String contentType = file.getContentType();
        System.out.println("文件类型:" + contentType);
        // 保存文件
        String savePath = "D:/uploads/";
        try {
            file.transferTo(new File(savePath + fileName));
            return "上传成功:" + fileName;
        } catch (IOException e) {
            return "上传失败:" + e.getMessage();
        }
    }
}

关键方法

Java如何获取上传文件的原始文件名?

  • getOriginalFilename():获取客户端提交的原始文件名,与Servlet中的getSubmittedFileName()功能一致。
  • getInputStream():获取文件输入流,可用于手动读取文件内容。
  • transferTo(File dest):将文件保存到指定路径。

Spring Boot简化配置

Spring Boot通过AutoConfiguration自动配置了文件上传组件,无需手动配置MultipartResolver,控制器代码与Spring MVC基本一致,但需在启动类上添加@EnableAutoConfiguration(默认已包含),Spring Boot允许在application.properties/yml中配置文件上传相关参数:

# 设置单个文件大小限制(默认1MB)
spring.servlet.multipart.max-file-size=10MB
# 设置总请求大小限制(默认10MB)
spring.servlet.multipart.max-request-size=100MB
# 临时文件存储路径(默认:系统临时目录)
spring.servlet.multipart.location=/tmp/uploads

第三方库的辅助处理

虽然Servlet和Spring已提供基础功能,但在复杂场景下(如支持断点续传、进度显示、文件重命名等),可借助第三方库(如Apache Commons FileUpload、CosMultipartRequest等)简化开发。

Apache Commons FileUpload

这是一个经典的文件上传组件,适用于Servlet环境,需配合commons-io使用,步骤如下:

  1. 添加依赖(Maven):

    <dependency>
     <groupId>commons-fileupload</groupId>
     <artifactId>commons-fileupload</artifactId>
     <version>1.4</version>
    </dependency>
    <dependency>
     <groupId>commons-io</groupId>
     <artifactId>commons-io</artifactId>
     <version>2.11.0</version>
    </dependency>
  2. 解析请求并获取文件名:

    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException {
     // 检查是否为multipart请求
     if (ServletFileUpload.isMultipartContent(request)) {
         // 配置上传参数
         DiskFileItemFactory factory = new DiskFileItemFactory();
         ServletFileUpload upload = new ServletFileUpload(factory);
         // 解析请求,获取FileItem列表
         List<FileItem> items = upload.parseRequest(request);
         for (FileItem item : items) {
             if (!item.isFormField()) {
                 // 获取原始文件名
                 String fileName = item.getName();
                 System.out.println("原始文件名:" + fileName);
                 // 处理文件(如保存)
                 File saveFile = new File("/path/to/save/" + fileName);
                 item.write(saveFile);
             }
         }
     }
    }

    说明FileItemgetName()方法返回原始文件名,但需注意不同浏览器可能返回路径(如C:\Users\user\Desktop\test.txt),需进一步处理提取纯文件名。

其他库

  • CosMultipartRequest:适用于Servlet环境,支持文件重命名和进度监听。
  • Apache Tika:可用于通过文件内容推断文件名或类型,适用于文件名缺失的场景。

文件名处理的注意事项

获取文件名后,直接使用可能存在安全风险,需进行校验和处理:

Java如何获取上传文件的原始文件名?

文件名安全校验

  • 防止路径遍历攻击:恶意用户可能通过文件名(如../../malicious.txt)尝试访问服务器敏感文件,需提取文件名中的纯名称部分,并过滤路径分隔符:

    String originalName = file.getOriginalFilename();
    // 提取文件名(去除路径)
    String fileName = new File(originalName).getName();
    // 过滤非法字符(如../、\、:等)
    fileName = fileName.replaceAll("[\\\\/:*?\"<>|]", "_");
  • 文件名长度限制:避免过长的文件名导致系统错误(如Windows文件名限制为255字符),可截断或生成唯一文件名:

    if (fileName.length() > 100) {
      fileName = fileName.substring(0, 100) + 
                 "_" + UUID.randomUUID().toString().substring(0, 8) + 
                 fileName.substring(fileName.lastIndexOf("."));
    }

文件名冲突处理

多用户上传同名文件时,可能覆盖已有文件,可通过以下方式避免:

  • UUID重命名:生成唯一文件名,保留原始扩展名:
    String extension = fileName.substring(fileName.lastIndexOf("."));
    String uniqueFileName = UUID.randomUUID().toString() + extension;
  • 时间戳+随机数:结合时间戳和随机数生成文件名:
    String uniqueFileName = System.currentTimeMillis() + "_" + 
                         (int)(Math.random() * 1000) + extension;

扩展名校验

根据业务需求限制文件类型,避免上传可执行文件或恶意脚本:

String allowedExtensions = ".jpg,.jpeg,.png,.pdf";
String fileExtension = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
if (!allowedExtensions.contains(fileExtension)) {
    throw new IllegalArgumentException("不支持的文件类型:" + fileExtension);
}

最佳实践总结

  1. 优先使用框架封装:Spring的MultipartFile提供了更简洁的API,推荐在Spring项目中优先使用。
  2. 严格校验文件名:始终过滤路径遍历字符、限制长度,并根据业务校验扩展名。
  3. 避免直接使用原始文件名:通过UUID或时间戳生成唯一文件名,防止冲突和安全问题。
  4. 配置合理的文件大小限制:在框架配置中设置max-file-sizemax-request-size,避免服务器资源耗尽。
  5. 异常处理:捕获文件操作中的IOException,并记录日志,便于排查问题。

通过以上方法,可以安全、高效地在Java应用中获取和处理上传文件的名称,为后续业务逻辑提供可靠的数据基础。

赞(0)
未经允许不得转载:好主机测评网 » Java如何获取上传文件的原始文件名?