Java实现的文件上传下载工具类完整实例【上传文件自动命名】

这里是Java实现的文件上传下载工具类完整实例【上传文件自动命名】的完整攻略。

1. 实现思路

文件上传下载是Web开发中非常常见的需求,Java提供了丰富的API和工具来实现文件上传下载的功能。这个工具类的实现思路如下:

  • 文件上传:通过Servlet规范提供的HttpServletRequest对象获取上传文件,将上传文件保存到指定目录中,并返回文件保存路径和文件名。
  • 文件下载:通过Servlet规范提供的HttpServletResponse对象将服务器上的文件输出到浏览器,实现文件下载。

在文件上传过程中,为了避免文件名冲突,可以通过自动命名的方式给上传文件命名。本例中用UUID作为文件名,保证文件名唯一。

2. 代码实现

具体实现时需要添加依赖项,本例所需依赖项为:

  • commons-fileupload:用于处理文件上传。
  • commons-io:提供对文件和流的实用操作。

首先,我们需要创建一个工具类FileUtil,该工具类提供了文件上传和下载两个方法。

package com.example.demo.util;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

public class FileUtil {

    /**
     * 上传文件
     *
     * @param request     HttpServletRequest对象
     * @param uploadPath  上传文件保存的目录
     * @param allowedType 允许上传的文件类型
     * @param maxFileSize 允许上传的最大文件大小,单位为字节
     * @return 上传文件保存的路径和文件名,例如:/uploads/42f61985-28a7-4707-a8c3-8d23d6e8afc0.jpg
     * @throws Exception 如果上传文件失败则抛出异常
     */
    public static String upload(HttpServletRequest request, String uploadPath, String[] allowedType, long maxFileSize) throws Exception {
        // 如果上传的是多个文件,使用下面的代码
        /*List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
        for (FileItem item : items) {
            if (!item.isFormField()) { // 如果是文件字段
                String fileName = item.getName(); // 获取上传文件的文件名
                if (fileName != null && !fileName.isEmpty()) {
                    File uploadedFile = new File(uploadPath, fileName);
                    item.write(uploadedFile);
                    return uploadedFile.getPath();
                }
            }
        }*/

        // 如果上传的是单个文件,使用下面的代码
        if (ServletFileUpload.isMultipartContent(request)) { // 判断是否是multipart/form-data类型的表单
            DiskFileItemFactory factory = new DiskFileItemFactory();
            factory.setSizeThreshold(1024 * 1024); // 设置缓冲区大小,这里是1MB
            factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); // 设置临时文件保存的目录,这里使用系统默认的目录

            ServletFileUpload uploader = new ServletFileUpload(factory);
            uploader.setFileSizeMax(maxFileSize); // 设置允许上传的最大文件大小
            uploader.setSizeMax(10 * maxFileSize); // 设置允许上传的总文件大小

            String fileName = null;
            InputStream is = null;
            OutputStream os = null;
            try {
                FileItem item = uploader.parseRequest(request).get(0); // 获取上传的文件
                fileName = item.getName(); // 获取上传文件的文件名
                is = item.getInputStream(); // 获取上传文件的输入流
                if (fileName != null && !fileName.isEmpty()) {
                    // 如果文件夹不存在,则创建文件夹
                    File uploadDir = new File(uploadPath);
                    if (!uploadDir.exists()) {
                        uploadDir.mkdir();
                    }
                    // 自动生成文件名
                    fileName = generateFileName(fileName);
                    File uploadedFile = new File(uploadDir.getPath() + File.separator + fileName);
                    os = new FileOutputStream(uploadedFile);
                    IOUtils.copy(is, os); // 将上传文件复制到服务器上
                    return uploadedFile.getPath();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                IOUtils.closeQuietly(is); // 关闭输入流,释放资源
                IOUtils.closeQuietly(os); // 关闭输出流,释放资源
            }
        }
        return null;
    }

    /**
     * 生成新文件名
     *
     * @param oldFileName 原文件名
     * @return 新文件名
     */
    private static String generateFileName(String oldFileName) {
        String suffix = oldFileName.substring(oldFileName.lastIndexOf("."));
        String uuid = UUID.randomUUID().toString();
        return uuid + suffix;
    }

    /**
     * 下载文件
     *
     * @param filePath   文件路径
     * @param response   HttpServletResponse对象
     * @param isDownload 是否需要下载,如果为false,则直接在浏览器中打开文件
     * @throws Exception 如果下载文件失败则抛出异常
     */
    public static void download(String filePath, HttpServletResponse response, boolean isDownload) throws Exception {
        // 获取文件
        File file = new File(filePath);
        if (!file.exists()) {
            response.sendError(404, "File not found!");
            return;
        }
        String fileName = file.getName();

        // 设置Content-Type
        String contentType = getContentType(fileName);
        response.setContentType(contentType);

        // 设置Content-Disposition
        if (isDownload) { // 下载文件
            String contentDisposition = "attachment;filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + "\"";
            response.setHeader("Content-Disposition", contentDisposition);
        } else { // 在浏览器中打开文件
            String contentDisposition = "inline;filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + "\"";
            response.setHeader("Content-Disposition", contentDisposition);
        }

        // 将文件输出到浏览器
        InputStream is = null;
        OutputStream os = null;
        try {
            is = new FileInputStream(file);
            os = response.getOutputStream();
            IOUtils.copy(is, os);
            response.flushBuffer();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(is); // 关闭输入流,释放资源
            IOUtils.closeQuietly(os); // 关闭输出流,释放资源
        }
    }

    /**
     * 获取Content-Type
     *
     * @param fileName 文件名
     * @return 文件对应的Content-Type
     */
    private static String getContentType(String fileName) {
        String contentType = "application/octet-stream";
        String ext = fileName.substring(fileName.lastIndexOf("."));
        if (".txt".equalsIgnoreCase(ext)) {
            contentType = "text/plain";
        } else if (".doc".equalsIgnoreCase(ext) || ".docx".equalsIgnoreCase(ext)) {
            contentType = "application/msword";
        } else if (".xls".equalsIgnoreCase(ext) || ".xlsx".equalsIgnoreCase(ext)) {
            contentType = "application/vnd.ms-excel";
        } else if (".ppt".equalsIgnoreCase(ext) || ".pptx".equalsIgnoreCase(ext)) {
            contentType = "application/vnd.ms-powerpoint";
        } else if (".pdf".equalsIgnoreCase(ext)) {
            contentType = "application/pdf";
        } else if (".jpg".equalsIgnoreCase(ext) || ".jpeg".equalsIgnoreCase(ext)) {
            contentType = "image/jpeg";
        } else if (".png".equalsIgnoreCase(ext)) {
            contentType = "image/png";
        } else if (".gif".equalsIgnoreCase(ext)) {
            contentType = "image/gif";
        }
        return contentType;
    }

}

接下来,我们使用FileUtil工具类来实现文件上传和下载。

2.1 文件上传示例

下面的示例演示了如何使用FileUtil工具类将文件上传到服务器,并返回文件保存的路径和文件名。

package com.example.demo.controller;

import com.example.demo.util.FileUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;

@RestController
public class FileUploadController {

    @PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        try {
            String[] allowedType = {"image/jpeg", "image/png"}; // 允许上传的文件类型
            long maxFileSize = 10 * 1024 * 1024; // 允许上传的最大文件大小,这里是10MB
            String uploadPath = request.getServletContext().getRealPath("/uploads");
            String filePath = FileUtil.upload(request, uploadPath, allowedType, maxFileSize);
            return "File uploaded successfully: " + filePath;
        } catch (Exception e) {
            e.printStackTrace();
            return "File uploaded failed.";
        }
    }

}

2.2 文件下载示例

下面的示例演示了如何使用FileUtil工具类从服务器下载文件。

package com.example.demo.controller;

import com.example.demo.util.FileUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

@RestController
public class FileDownloadController {

    @GetMapping("/download/{fileName}")
    public void download(@PathVariable("fileName") String fileName, @RequestParam(value = "isDownload", required = false, defaultValue = "true") boolean isDownload, HttpServletResponse response) {
        try {
            String filePath = "/path/to/uploads/" + fileName;
            FileUtil.download(filePath, response, isDownload);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

以上就是Java实现的文件上传下载工具类完整实例【上传文件自动命名】的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现的文件上传下载工具类完整实例【上传文件自动命名】 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 记一次Flink遇到性能瓶颈

    前言 这周的主要时间花在Flink上面,做了一个简单的从文本文件中读取数据,然后存入数据库的例子,能够正常的实现功能,但是遇到个问题,我有四台机器,自己搭建了一个standalone的集群,不论我把并行度设置多少,跑起来的耗时都非常接近,实在是百思不得其解。机器多似乎并不能帮助它。 把过程记录在此,看后面随着学习的深入能不能解答出这个问题。 尝试过的修复方法…

    Java 2023年4月17日
    00
  • Spring Security认证器实现过程详解

    Spring Security认证器实现过程详解 Spring Security是用于保护Web应用程序的开放源代码框架。它可以提供基于角色的安全性,对用户进行身份验证和访问控制来保护应用程序。本文将详细介绍Spring Security认证器实现的过程。 一. Spring Security认证器 Spring Security提供了一个框架来处理所有We…

    Java 2023年6月3日
    00
  • Spring @Bean vs @Service注解区别

    下面是关于Spring中@Bean和@Service注解的详细讲解。 1. @Bean注解 1.1 概述 @Bean注解是用来注册一个Java Bean对象的,它是放在方法上的注解。当Spring的容器启动时,会去扫描所有带有这个注解的方法并执行它,最终返回的对象会被放到Spring的容器中。 1.2 示例说明 假设有一个用户服务的实现类UserServic…

    Java 2023年5月31日
    00
  • Spring Security 过滤器注册脉络梳理

    下面是Spring Security 过滤器注册脉络梳理的完整攻略。 Spring Security 过滤器注册脉络梳理 在Spring Security中,过滤器的注册是非常重要的一项工作,它决定了Spring Security能否对请求进行拦截,并进行相应的安全控制。 过滤器链 Spring Security 采用了一条链式过滤器来完成安全控制,它是由一…

    Java 2023年5月20日
    00
  • SpringBoot扩展SpringMVC原理并实现全面接管

    对于这个话题,首先我们需要了解SpringMVC框架和SpringBoot框架的基本概念,然后再探讨SpringBoot如何扩展和接管SpringMVC框架的原理,最后给出具体实现的示例。 SpringMVC和SpringBoot框架的基本概念 SpringMVC框架 SpringMVC框架是一种基于Java的Web框架,它提供了一种轻量级的方式来构建Web…

    Java 2023年5月16日
    00
  • Java中数据库常用的两把锁之乐观锁和悲观锁

    Java中数据库常用的两把锁是乐观锁和悲观锁。 什么是乐观锁和悲观锁? 悲观锁 悲观锁假定在执行操作时会产生并发冲突,因此在操作数据前先加锁,确保操作数据时不会被其他人修改。悲观锁的典型实现就是数据库中的行锁、表锁。 在Java中,悲观锁常用的实现就是synchronized关键字和ReentrantLock类。 乐观锁 乐观锁假定在执行操作时不会产生并发冲…

    Java 2023年5月19日
    00
  • 用java生成html文件实现原理及代码

    生成HTML文件的实现原理: 要实现用Java程序生成HTML文件,需要使用Java IO和字符串操作技术。生成HTML文件的步骤如下: 创建一个文本文件,并给定后缀名为“.html”; 在文件中编写HTML代码; 使用Java IO将HTML代码写入到创建的文本文件中; Java代码示例1: import java.io.FileWriter; impor…

    Java 2023年5月26日
    00
  • Spring Boot企业常用的starter示例详解

    Spring Boot企业常用Starter示例详解 Spring Boot是一个开源框架,它能搭建现代化的Java Web和微服务应用。Spring Boot以可靠地方式管理依赖项和自动配置Spring应用为特点,这使得开发者可以集中精力解决业务问题,而不是传统的Spring框架配置。Spring Boot提供了许多Starter项目,能够快速方便地集成常…

    Java 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部