Java Web實現(xiàn)文件上傳和下載接口功能詳解
1.上傳java代碼實現(xiàn)
@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代碼實現(xiàn)
文件下載除了靜態(tài)訪問(及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("你沒有權(quán)限訪問 " + 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 訪問權(quán)限異常類
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;
}
}圖片示例



完整代碼請參考:https://gitee.com/taisan/tarzan-navigation
到此這篇關(guān)于Java Web實現(xiàn)文件上傳和下載接口功能詳解的文章就介紹到這了,更多相關(guān)Java Web文件上傳下載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Spring開啟@Async異步方式(javaconfig配置)
這篇文章主要介紹了使用Spring開啟@Async異步方式(javaconfig配置),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
springboot集成nacos實現(xiàn)自動刷新的示例代碼
研究nacos時發(fā)現(xiàn),springboot版本可使用@NacosValue實現(xiàn)配置的自動刷新,本文主要介紹了springboot集成nacos實現(xiàn)自動刷新的示例代碼,感興趣的可以了解一下2023-11-11
SpringCloud Gateway HttpWebHandlerAdapter鏈路調(diào)用請求流程介
Spring Cloud Gateway旨在為微服務架構(gòu)提供一種簡單有效的、統(tǒng)一的 API 路由管理方式。Spring Cloud Gateway 作為 Spring Cloud 生態(tài)系中的網(wǎng)關(guān),它不僅提供統(tǒng)一的路由方式,并且基于 Filter 鏈的方式提供了網(wǎng)關(guān)基本的功能,例如:安全、監(jiān)控/埋點和限流等2022-10-10
IDEA配置Tomcat后,控制臺tomcat?catalina?log出現(xiàn)亂碼問題
本文介紹了如何通過設置Tomcat和IDEA的編碼格式來解決編碼問題,首先嘗試修改Tomcat的logging.properties文件中的編碼設置,如果未解決問題,則調(diào)整IDEA的編碼設置,通過修改vmoptions文件來全局設置IDEA的編碼格式,作者分享了個人成功解決問題的方法和步驟,供其他開發(fā)者參考2024-09-09
Java 輕松實現(xiàn)二維數(shù)組與稀疏數(shù)組互轉(zhuǎn)
在某些應用場景中需要大量的二維數(shù)組來進行數(shù)據(jù)存儲,但是二維數(shù)組中卻有著大量的無用的位置占據(jù)著內(nèi)存空間,稀疏數(shù)組就是為了優(yōu)化二維數(shù)組,節(jié)省內(nèi)存空間2022-04-04
使用spring boot開發(fā)時java對象和Json對象轉(zhuǎn)換的問題
這篇文章主要介紹了使用spring boot開發(fā)時java對象和Json對象轉(zhuǎn)換的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03

