JAVA前端上传文件后端接收文件并保存在本地

前言

在一些情境下,用户通过浏览器上传word、excel、pdf等各种类型的文件到系统,上传后可以随时下载。下载文件可以通过虚拟路径的方式访问虚拟路径通过浏览器下载;也可以后端直接发送文件流给前端完成下载,发送文件到网页并从网页下载文件

上传文件

控制层接口
java 复制代码
 @RequestMapping(value = "/action/upload/new/file/release", method = RequestMethod.POST)
    public EiInfo uploadNewActionFileRelease(MultipartFile[] files) {
        EiInfo eiInfo = new EiInfo();
        ResultMessage resultMessage = service.uploadFile(files[0]);
        return ReturnOutInfo.outInfoSuccess(eiInfo, "上传文件成功");
    }
服务层处理
java 复制代码
	// 文件保存路径写在了yml文件中
    @Value("${file.path.local}")
    private String fileLocalPath;

@Override
    public ResultMessage uploadFile(MultipartFile file) {
        try {
            // 封装文件信息
            FileSaveDTO fileSaveDTO = FileUtil.handleFileSave(fileLocalPath, file);
            return new ResultMessage(1, "文件上传成功");
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultMessage(-1, e.getMessage());
        }
    }
application.yml配置文件保存路径
yml 复制代码
file:
  path:
    local:
      D:/JavaCode/bao_safety_management_system/bao_safety_platform_system/safe_file/
    # img/
    tomcat:
      http://192.168.0.58:8189/safety-platform/safe/file/
文件工具类 FileUtil

工具类中有保存文件和下载文件两个方法。

java 复制代码
public class FileUtil {

    private static SimpleDateFormat sfFile = new SimpleDateFormat("yyyyMMddHHmmss");

    public static FileSaveDTO handleFileSave(String localPath, MultipartFile file) throws Exception {
        // 处理传来的文件
        String name = file.getOriginalFilename();
        String saveName = "file-" + sfFile.format(new Date()) + UUID.randomUUID().toString().substring(0, 4) + name.substring(name.lastIndexOf("."));
        File saveFile = new File(localPath + saveName);
        file.transferTo(saveFile);

        // 判断文件是否是图片类型
        // Path path = saveFile.toPath();
        // String type = Files.probeContentType(path);
        if (Files.probeContentType(saveFile.toPath()) != null) {
            return new FileSaveDTO(name, saveName, Files.probeContentType(saveFile.toPath()).startsWith("image/"));
        } else {
            return new FileSaveDTO(name, saveName, false);
        }
    }

    public static boolean downloadFile(File file, String fileName, HttpServletResponse response) throws Exception {
        // 清空缓冲区,状态码和响应头(headers)
        response.reset();
        // 设置ContentType,响应内容为二进制数据流,编码为utf-8,此处设定的编码是文件内容的编码
        response.setContentType("application/octet-stream;charset=utf-8");
        // 以(Content-Disposition: attachment; filename="filename.jpg")格式设定默认文件名,设定utf编码,此处的编码是文件名的编码,使能正确显示中文文件名
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ";filename*=utf-8''" + URLEncoder.encode(fileName, "utf-8"));

        // 实现文件下载
        byte[] buffer = new byte[1024 * 1024 * 1024];
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        try {
            fis = new FileInputStream(file);
            bis = new BufferedInputStream(fis);
            // 获取字节流
            OutputStream os = response.getOutputStream();
            int i = bis.read(buffer);
            while (i != -1) {
                os.write(buffer, 0, i);
                i = bis.read(buffer);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
文件信息

文件保存在本地后,将文件信息封装到一个对象中返回给调用保存文件功能的方法中,方便下一步操作

java 复制代码
public class FileSaveDTO {
    private String actualName = "";/*文件名字*/
    private String saveName = "";/*保存在本地时文件名*/
    private Boolean isImage = false;/*是否是图片文件*/

    public FileSaveDTO() {
    }

    public FileSaveDTO(String actualName, String saveName, Boolean isImage) {
        this.actualName = actualName;
        this.saveName = saveName;
        this.isImage = isImage;
    }

    public String getActualName() {
        return actualName;
    }

    public void setActualName(String actualName) {
        this.actualName = actualName;
    }

    public String getSaveName() {
        return saveName;
    }

    public void setSaveName(String saveName) {
        this.saveName = saveName;
    }

    public Boolean getImage() {
        return isImage;
    }

    public void setImage(Boolean image) {
        isImage = image;
    }
}

浏览器中使用虚拟路径下载文件

通过如下配置,前端在浏览器中可以通过虚拟路径直接下载文件

http://192.168.0.58:8189/safety-platform/safe/file/xxx.docx
java 复制代码
@Configuration
public class WebFileConfig implements WebMvcConfigurer {


    @Value("${file.path.local}")
    private String fileLocalPath;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/safe/file/**").addResourceLocations("file:" + fileLocalPath);
    }
}
相关推荐
奋斗的小花生9 分钟前
c++ 多态性
开发语言·c++
魔道不误砍柴功12 分钟前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_23412 分钟前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨15 分钟前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
老猿讲编程42 分钟前
一个例子来说明Ada语言的实时性支持
开发语言·ada
王哈哈^_^1 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
Chrikk2 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*2 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue2 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man2 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang