首页 > 编程语言 >Java Web 实现文件上传和下载接口功能

Java Web 实现文件上传和下载接口功能

时间:2023-11-25 10:22:21浏览次数:29  
标签:Web Java IOException file path null 上传 throws must

1.上传java代码实现
@ResponseBody
@PostMapping("/upload")
public ResponseVo upload(@RequestParam(value = "file", required = false) MultipartFile multipartFile) {
File file=new File("上传到服务器的文件地址");
try {
FileUtil.copy(multipartFile.getBytes(), file);
} catch (IOException e) {
return ResultUtil.error();
}
return ResultUtil.success();
}
上传用post或者get请求都可以,这里代码中用post做的示例。

2.文件流下载java代码实现
文件下载除了静态访问(及nginx、tomcat等服务器映射到后的文件web路径)下载以外 ,还可以通过流的方式下载,代码如下:

/**
* 下载
*/
@PostMapping("/download")
public void download(String fileName, HttpServletResponse response) throws IOException {
FileInputStream fis=new FileInputStream("服务器文件所在路径");
response.addHeader("Content-Disposition", "attachment;filename="+fileName+";"+"filename*=utf-8''"+fileName);
FileUtil.copy(fis, response.getOutputStream());
}
上传用post或者get请求都可以,这里代码中用post做的示例。

3.Fileutil工具类代码:

import com.tarzan.navigation.common.exception.ForbiddenException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
import org.springframework.util.StreamUtils;

import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

@Slf4j
public class FileUtil {

/**
* Copies folder.
*
* @param source source path must not be null
* @param target target path must not be null
*/
public static void copyFolder(@NonNull Path source, @NonNull Path target) throws IOException {
Assert.notNull(source, "Source path must not be null");
Assert.notNull(target, "Target path must not be null");

Files.walkFileTree(source, new SimpleFileVisitor<Path>() {

@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
Path current = target.resolve(source.relativize(dir).toString());
Files.createDirectories(current);
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
Files.copy(file, target.resolve(source.relativize(file).toString()),
StandardCopyOption.REPLACE_EXISTING);
return FileVisitResult.CONTINUE;
}
});
}

/**
* Deletes folder recursively.
*
* @param deletingPath deleting path must not be null
*/
public static void deleteFolder(@NonNull Path deletingPath) {
Assert.notNull(deletingPath, "Deleting path must not be null");

if (Files.notExists(deletingPath)) {
return;
}
log.info("Deleting [{}]", deletingPath);
delete(deletingPath.toFile());
log.info("Deleted [{}] successfully", deletingPath);
}

private static void delete(File file) {
if(file.isDirectory()){
Arrays.asList(Objects.requireNonNull(file.listFiles())).forEach(FileUtil::delete);
}
file.delete();
}

/**
* Renames file or folder.
*
* @param pathToRename file path to rename must not be null
* @param newName new name must not be null
*/
public static void rename(@NonNull Path pathToRename, @NonNull String newName)
throws IOException {
Assert.notNull(pathToRename, "File path to rename must not be null");
Assert.notNull(newName, "New name must not be null");

Path newPath = pathToRename.resolveSibling(newName);
log.info("Rename [{}] to [{}]", pathToRename, newPath);

Files.move(pathToRename, newPath);

log.info("Rename [{}] successfully", pathToRename);
}



/**
* Unzips content to the target path.
*
* @param zis zip input stream must not be null
* @param targetPath target path must not be null and not empty
* @throws IOException throws when failed to access file to be unzipped
*/
public static void unzip(@NonNull ZipInputStream zis, @NonNull Path targetPath)
throws IOException {
// 1. unzip file to folder
// 2. return the folder path
Assert.notNull(zis, "Zip input stream must not be null");
Assert.notNull(targetPath, "Target path must not be null");

// Create path if absent
createIfAbsent(targetPath);

// Folder must be empty
ensureEmpty(targetPath);

ZipEntry zipEntry = zis.getNextEntry();

while (zipEntry != null) {
// Resolve the entry path
Path entryPath = targetPath.resolve(zipEntry.getName());

// Check directory
checkDirectoryTraversal(targetPath, entryPath);

if (zipEntry.isDirectory()) {
// Create directories
Files.createDirectories(entryPath);
} else {
// Copy file
Files.copy(zis, entryPath);
}

zipEntry = zis.getNextEntry();
}
}

/**
* Unzips content to the target path.
*
* @param bytes zip bytes array must not be null
* @param targetPath target path must not be null and not empty
* @throws IOException io exception
*/
public static void unzip(@NonNull byte[] bytes, @NonNull Path targetPath) throws IOException {
Assert.notNull(bytes, "Zip bytes must not be null");

ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(bytes));
unzip(zis, targetPath);
}

/**
* Zips folder or file.
*
* @param pathToZip file path to zip must not be null
* @param pathOfArchive zip file path to archive must not be null
* @throws IOException throws when failed to access file to be zipped
*/
public static void zip(@NonNull Path pathToZip, @NonNull Path pathOfArchive)
throws IOException {
try (OutputStream outputStream = Files.newOutputStream(pathOfArchive)) {
try (ZipOutputStream zipOut = new ZipOutputStream(outputStream)) {
zip(pathToZip, zipOut);
}
}
}

/**
* Zips folder or file.
*
* @param pathToZip file path to zip must not be null
* @param zipOut zip output stream must not be null
* @throws IOException throws when failed to access file to be zipped
*/
public static void zip(@NonNull Path pathToZip, @NonNull ZipOutputStream zipOut)
throws IOException {
// Zip file
zip(pathToZip, pathToZip.getFileName().toString(), zipOut);
}

/**
* Zips folder or file.
*
* @param fileToZip file path to zip must not be null
* @param fileName file name must not be blank
* @param zipOut zip output stream must not be null
* @throws IOException throws when failed to access file to be zipped
*/
private static void zip(@NonNull Path fileToZip, @NonNull String fileName,
@NonNull ZipOutputStream zipOut) throws IOException {
if (Files.isDirectory(fileToZip)) {
log.debug("Try to zip folder: [{}]", fileToZip);
// Append with '/' if missing
String folderName =
StringUtils.appendIfMissing(fileName, File.separator, File.separator);
// Create zip entry and put into zip output stream
zipOut.putNextEntry(new ZipEntry(folderName));
// Close entry for writing the next entry
zipOut.closeEntry();

// Iterate the sub files recursively
try (Stream<Path> subPathStream = Files.list(fileToZip)) {
// There should not use foreach for stream as internal zip method will throw
// IOException
List<Path> subFiles = subPathStream.collect(Collectors.toList());
for (Path subFileToZip : subFiles) {
// Zip children
zip(subFileToZip, folderName + subFileToZip.getFileName(), zipOut);
}
}
} else {
// Open file to be zipped
// Create zip entry for target file
ZipEntry zipEntry = new ZipEntry(fileName);
// Put the entry into zip output stream
zipOut.putNextEntry(zipEntry);
// Copy file to zip output stream
Files.copy(fileToZip, zipOut);
// Close entry
zipOut.closeEntry();
}
}

/**
* Creates directories if absent.
*
* @param path path must not be null
* @throws IOException io exception
*/
public static void createIfAbsent(@NonNull Path path) throws IOException {
Assert.notNull(path, "Path must not be null");

if (Files.notExists(path)) {
// Create directories
Files.createDirectories(path);

log.debug("Created directory: [{}]", path);
}
}

/**
* The given path must be empty.
*
* @param path path must not be null
* @throws IOException io exception
*/
public static void ensureEmpty(@NonNull Path path) throws IOException {
if (!isEmpty(path)) {
throw new DirectoryNotEmptyException("Target directory: " + path + " was not empty");
}
}

/**
* Checks directory traversal vulnerability.
*
* @param parentPath parent path must not be null.
* @param pathToCheck path to check must not be null
*/
public static void checkDirectoryTraversal(@NonNull String parentPath,
@NonNull String pathToCheck) {
checkDirectoryTraversal(Paths.get(parentPath), Paths.get(pathToCheck));
}

/**
* Checks directory traversal vulnerability.
*
* @param parentPath parent path must not be null.
* @param pathToCheck path to check must not be null
*/
public static void checkDirectoryTraversal(@NonNull Path parentPath,
@NonNull String pathToCheck) {
checkDirectoryTraversal(parentPath, Paths.get(pathToCheck));
}

/**
* Checks directory traversal vulnerability.
*
* @param parentPath parent path must not be null.
* @param pathToCheck path to check must not be null
*/
public static void checkDirectoryTraversal(@NonNull Path parentPath,
@NonNull Path pathToCheck) {
Assert.notNull(parentPath, "Parent path must not be null");
Assert.notNull(pathToCheck, "Path to check must not be null");

if (pathToCheck.normalize().startsWith(parentPath)) {
return;
}

throw new ForbiddenException("你没有权限访问 " + pathToCheck);
}

/**
* Checks if the given path is empty.
*
* @param path path must not be null
* @return true if the given path is empty; false otherwise
* @throws IOException io exception
*/
public static boolean isEmpty(@NonNull Path path) throws IOException {
Assert.notNull(path, "Path must not be null");

if (!Files.isDirectory(path) || Files.notExists(path)) {
return true;
}

try (Stream<Path> pathStream = Files.list(path)) {
return !pathStream.findAny().isPresent();
}
}
/**
* Copy the contents of the given input File to the given output File.
* @param in the file to copy from
* @param out the file to copy to
* @return the number of bytes copied
* @throws IOException in case of I/O errors
*/
public static int copy(File in, File out) throws IOException {
Assert.notNull(in, "No input File specified");
Assert.notNull(out, "No output File specified");
return copy(Files.newInputStream(in.toPath()), Files.newOutputStream(out.toPath()));
}

/**
* Copy the contents of the given byte array to the given output File.
* @param in the byte array to copy from
* @param out the file to copy to
* @throws IOException in case of I/O errors
*/
public static void copy(byte[] in, File out) throws IOException {
Assert.notNull(in, "No input byte array specified");
Assert.notNull(out, "No output File specified");
copy(new ByteArrayInputStream(in), Files.newOutputStream(out.toPath()));
}

/**
* Copy the contents of the given InputStream to the given OutputStream.
* Closes both streams when done.
* @param in the stream to copy from
* @param out the stream to copy to
* @return the number of bytes copied
* @throws IOException in case of I/O errors
*/
public static int copy(InputStream in, OutputStream out) throws IOException {
Assert.notNull(in, "No InputStream specified");
Assert.notNull(out, "No OutputStream specified");

try {
return StreamUtils.copy(in, out);
}
finally {
try {
in.close();
}
catch (IOException ex) {
}
try {
out.close();
}
catch (IOException ex) {
}
}
}
/**
* Copy the contents of the given byte array to the given OutputStream.
* Closes the stream when done.
* @param in the byte array to copy from
* @param out the OutputStream to copy to
* @throws IOException in case of I/O errors
*/
public static void copy(byte[] in, OutputStream out) throws IOException {
Assert.notNull(in, "No input byte array specified");
Assert.notNull(out, "No OutputStream specified");

try {
out.write(in);
}
finally {
try {
out.close();
}
catch (IOException ex) {
}
}
}


}

ForbiddenException 访问权限异常类


import org.springframework.http.HttpStatus;

/**
* Exception caused by accessing forbidden resources.
*
* @author johnniang
*/
public class ForbiddenException extends RuntimeException {

public ForbiddenException() {
super();
}

public ForbiddenException(String message) {
super(message);
}

public ForbiddenException(String message, Throwable cause) {
super(message, cause);
}

public HttpStatus getStatus() {
return HttpStatus.FORBIDDEN;
}
}

图片示例

 

 

 

 

 

 

完整代码请参考:

tarzan-navigation: 泰山导航网站-java版

4.相关知识
MultipartFile、HttpServletResponse和FileInputStream都是在Java Web开发中常用的类。它们分别用于处理上传文件、响应HTTP请求和读取文件内容。下面将详细解释这三个类的特点和用法。

MultipartFile:

MultipartFile是Spring框架提供的接口,用于处理上传的文件数据。它提供了一组方法来获取文件名、文件类型、文件大小以及文件内容等信息。

以下是MultipartFile接口中常用的方法:

getOriginalFilename():获取上传文件的原始文件名。
getContentType():获取上传文件的内容类型。
getSize():获取上传文件的大小。
getBytes():获取上传文件的字节数组。
getInputStream():获取上传文件的输入流。
HttpServletResponse:

HttpServletResponse是Java Servlet API提供的接口,用于向客户端发送HTTP响应。通过HttpServletResponse,我们可以设置响应的状态码、头部信息和内容等。

以下是HttpServletResponse接口中常用的方法:

setStatus(int sc):设置HTTP响应的状态码。
setHeader(String name, String value):设置HTTP响应的头部信息。
getWriter():获取输出流,用于将数据写入响应体。
FileInputStream:

FileInputStream是Java IO提供的类,用于读取文件内容。它继承自InputStream,可以打开一个文件并从中读取字节数据。

以下是FileInputStream类常用的方法:

read():读取单个字节的数据。
read(byte[] b):将最多b.length个字节的数据读入到字节数组b中。
close():关闭输入流。
总结:

MultipartFile用于处理上传的文件数据,HttpServletResponse用于向客户端发送HTTP响应,FileInputStream用于读取文件内容。它们在Java Web开发中起着重要的作用,能够处理文件上传、下载和读取等常见任务。希望以上内容对您有所帮助,如有任何疑问,请随时提问。

 

参考文章:http://blog.ncmem.com/wordpress/2023/11/25/java-web-%e5%ae%9e%e7%8e%b0%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd%e6%8e%a5%e5%8f%a3%e5%8a%9f%e8%83%bd/

欢迎入群一起讨论

 

 

标签:Web,Java,IOException,file,path,null,上传,throws,must
From: https://www.cnblogs.com/songsu/p/17855246.html

相关文章

  • 【开源】基于JavaWeb的快乐贩卖馆管理系统 毕业设计
    一、摘要1.1项目介绍基于JAVA+Vue+SpringBoot+MySQL的快乐贩卖馆管理系统,包含了视频模块、视频收藏模块、视频打分模块、视频交友模块、视频购物车模块和视频订单模块,还包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管理、文件管理、图表展示等基础......
  • Java零基础入门-数组
    Java零基础入门-数组前言Java是一门面向对象的编程语言,被广泛应用于各个领域。数组是Java编程中最基本也是最重要的数据结构之一,它可以用来存储一组数据,并且方便进行操作和处理。本文将为大家介绍Java数组的基本概念、语法和常见应用场景,帮助初学者快速入门。摘要本文将从以下......
  • 【开源】基于JavaWeb的智慧家政系统 毕业设计
    一、摘要1.1项目介绍基于微信小程序+JAVA+Vue+SpringBoot+MySQL的智慧家政系统,包含了地址管理模、订单管理、家政分类管理、家政服务管理、用户反馈管理模块,还包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管理、文件管理、图表展示等基础模块,基于微......
  • Java二级医院区域HIS信息管理系统源码(SaaS服务)
    一个好的HIS系统,要具有开放性,便于扩展升级,增加新的功能模块,支撑好医院的业务的拓展,而且可以反过来给医院赋能,最终向更多的患者提供更好的服务。系统采用前后端分离架构,前端由Angular、JavaScript开发;后端使用Java语言开发。融合B/S版电子病历系统,支持电子病历四级。系统运行稳定、......
  • Java报表详情介绍及示例程
    Java报表详情介绍及示例程序简介Java报表是一种用于展示数据并提供可视化分析的工具。它可以将数据转化为图表、表格、图像等形式,帮助用户更直观地理解数据的含义和趋势。Java报表通常用于企业管理、数据分析、业务决策等领域,具有易于使用、灵活性高、功能强大等特点。常用的Java报......
  • java Calendar、LocalDateTime、LocalDate日期加减
    Calendar日期获取,设置,加减创建一个日历对象获取当前年份,月份,日期等.....设置指定年份,月份,日期等.....Calendarcalendar=Calendar.getInstance();//创建一个日历对象intyear=calendar.get(calendar.YEAR);//获取当前年份System.out.p......
  • 在.Net中使用Java代码?
    前言你没有看错,我确实在.Net6的项目中在编写java,我都usingjava了,算不算在写java那?usingcom.microsoft.sqlserver.jdbc;usingjava.sql;并且编辑器还带提示的功能这一切都是借助IKVM来实现的,或许有些人还听说过使用IKVM的CLI命令来转换jar包,比如使用Bing搜索:ikvm转换jar包......
  • 5-Windows系统上安装java
      有一些生信软件是java语言写的,就需要安装java才能运行,下面展示java的安装。 1,下载(https://www.oracle.com/java/technologies/downloads/#java17) 官网下载java2,双击安装,这里的安装位置最好按照默认的来,不更改,在C盘。 安装3,配置环境变量,为了让任何目录......
  • Web API(一些记录)
    WebAPI(一些记录)1.注意当使用间隔函数的时候做轮播图,点点的效果,删除需要放在间隔函数内,不能在函数外面声明,在外面的话删的点就固定了,放里面就是每执行一次就再选择一次2.i--在事件点击函数里面也是立马执行吗,不是先把函数里面的其他东西执行完,再执行i--吗?答:是的因为i--它是独......
  • Java21虚拟线程实践
    Java21虚拟线程实践一个月之前,java21正式版发布了,作为继java17之后的又一个长期支持版本(LTS),为我们带来了很多新的特性,其中我最感兴趣的就是虚拟线程(virtualthread),相信大家对虚拟线程也很好奇。趁着空闲时间安装了jdk21来体验一把,顺便把我查到的关于java21虚拟线程相关的资料......