笔记:
更新时间: 2025年5月13日13:43:01
1. 我的环境:JDK 1.8 + Centos 9 + Nginx 1.2
2. 在 /home 下面创建了一个文件夹: /home/chengdong/upload/images 存放图片
# 创建目录 -p 递归创建目录
mkdir -p /home/chengdong/upload/images
文件夹所属组: 因为我的 nginx 是root用户组,所以 /home/chengdong/upload/images 这个路径也是设置的root组
文件夹的权限:755 确保你要上传文件的目标目录具有正确的权限设置,允许 Nginx 进程进行写入
# 修改权限
sudo chmod -R 755 /home/chengdong/upload/images
# 修改所属组
sudo chown -R root:root /home/chengdong/upload/images
3. 配置 Nginx
http {
# 设置请求头的最大限制,一定放在http{} 里面,不要放在server
# 前端request 响应时间也需要修改
client_max_body_size 100M; # 设置允许上传的最大文件大小
}
# 文件服务器
server {
listen 80;
server_name upload.xxxxx.email; # 域名或者ip地址
# 访问根路径时自动跳转到 /upload
location = / {
return 301 /upload;
}
location /upload {
alias /home/chengdong/upload/images/;
allow all; # 允许所有IP访问
autoindex on; # 启用目录列表功能,当访问文件夹时显示文件列表
dav_methods PUT; # 允许put推送
}
}
# 重启nginx
sudo systemctl restart nginx
4. Java 代码,添加依赖:有两种手动添加和使用Springboot 集成的
<!-- 文件传输 -->
<!-- Jersey 核心 -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.39</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.39</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.39</version>
</dependency>
<!-- 如果使用 JSON 处理 -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>2.39</version>
</dependency>
<!-- 如果你使用的是Spring boot 可以只添加下面的即可-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
5. 代码
import org.apache.commons.io.FilenameUtils;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.UUID;
public class Upload {
public static String Files_Server_Path = "http://upload.xxxxx.email/upload/images/";
public static void main(String[] args) {
String filePath = "E:\\3000系列\\3006.png"; // 本地文件路径
try {
// 读取本地文件为字节数组
byte[] fileBytes = Files.readAllBytes(Paths.get(filePath));
File file = new File(filePath);
String fileName = file.getName();
String fileSuffixName = ""; // 文件的后缀名
if (fileName != null && fileName.lastIndexOf(".") != -1) {
fileSuffixName = fileName.substring(fileName.lastIndexOf(".") + 1);
}
// 调用上传方法
uploadFile(fileBytes, fileSuffixName);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 将文件推送到 nginx 文件服务器
* @param fileBytes 文件字节
* @param fileSuffixName 文件的后缀名
*/
public static String uploadFile(byte[] fileBytes, String fileSuffixName) {
String lastFilePath = "";
Client client = ClientBuilder.newClient();
try {
// 将传入的文件后缀名与 UUID 拼接
String filename = UUID.randomUUID().toString().replace("-", "") + "." + fileSuffixName;
// 确保文件服务路径不以斜杠结尾
if (Files_Server_Path.endsWith("/"))
Files_Server_Path = Files_Server_Path.substring(0, Files_Server_Path.length() - 1);
WebTarget target = client.target(Files_Server_Path + "/" + filename);
// 使用PUT方法上传文件
Response response = target.request()
.header("Content-Disposition", "attachment; filename=\"" + filename + "\"")
.put(Entity.entity(fileBytes, MediaType.APPLICATION_OCTET_STREAM));
// 处理响应
if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) {
System.out.println("文件上传成功!");
System.out.println("上传路径: " + Files_Server_Path + "/" + filename);
lastFilePath = Files_Server_Path + "/" + filename;
return lastFilePath;
} else {
System.out.println("文件上传失败!状态码: " + response.getStatus());
System.out.println("错误详情: " + response.readEntity(String.class));
}
} finally {
client.close();
}
return lastFilePath;
}
}
6:执行效果

下面是使用VUE + Spring boot 的一个简单demo 可做参考:
<!--vue html 代码-->
<el-form-item label="商品图片">
<el-upload ref="uplaod" action="" list-type="picture-card" :on-preview="handlePictureCardPreview"
:on-remove="handleRemove" :limit="1" :on-change="handleUploadChange" :auto-upload="false">
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="mainImageUrl" alt="">
</el-dialog>
</el-form-item>
// javaScript 的代码
// 上传商品图片
export function uploadProductImge(data) {
return request({
url: '/product/save/upload',
method: 'post',
headers: {
'Content-Type': 'multipart/form-data',
},
data: data
})
}
<script>
import { uploadProductImge } from "@/api/product/save";
export default {
data() {
return {
mainImageUrl: '',
dialogVisible: false,
// 省略.....
}
},
methods: {
handleUploadChange(file, fileList) {
const formData = new FormData();
formData.append('file', file.raw);
uploadProductImge(formData).then(response => {
console.log(response);
}).catch(error => {
console.error('上传失败:', error);
});
}
},
// 上传之后预览
handlePictureCardPreview(file) {
this.mainImageUrl = file.url;
this.dialogVisible = true;
},
// 移除
handleRemove(file, fileList) {
console.log(file, fileList);
}
}
</script>
// Controller 后端代码
@PostMapping("/upload")
public AjaxResult upload(@RequestParam("file") MultipartFile file)
{
if (null == file)
return error("请选择文件");
String fileUrl = null;
try {
String fileName = file.getOriginalFilename();
String fileSuffixName = ""; // 文件的后缀名
if (fileName != null && fileName.lastIndexOf(".") != -1) {
fileSuffixName = fileName.substring(fileName.lastIndexOf(".") + 1);
}
UploadUtils.uploadFile(file.getBytes(), fileSuffixName);
} catch (Exception e) {
throw new RuntimeException("文件上传失败");
}
return success(fileUrl);
}
}
还有一个简洁版,使用Spring Boot 自带的
RestTemplate, 只需要下面的代码即可
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.UUID;
/**
* 文件上传帮助类
* @author chengdong
* @Date 2025年4月30日11:47:11
*/
@Component
public class UploadUtils {
private static String serverUploadPath;
@Value("${server-uplaod-path}")
public void setServerUploadPath(String path) {
serverUploadPath = path;
}
public static String getServerUploadPath() {
return serverUploadPath;
}
/**
* 上传文件到指定服务器路径
* @param fileBytes 文件内容的字节数组
* @param fileSuffixName 文件后缀名(如:jpg、png等)
* @return 文件上传后的完整访问路径(如果上传失败,返回空字符串)
*/
public static String uploadFile(byte[] fileBytes, String fileSuffixName) {
String url = ""; // 最终返回的文件访问路径
// 1. 生成唯一文件名:UUID去除横杠 + 文件后缀
String filename = UUID.randomUUID().toString().replace("-", "") + "." + fileSuffixName;
// 2. 创建RestTemplate实例(Spring提供的HTTP客户端)
// 注意:实际项目中建议通过@Bean注入,避免重复创建
RestTemplate restTemplate = new RestTemplate();
// 3. 设置请求头
HttpHeaders headers = new HttpHeaders();
// 设置内容类型为二进制流(适用于任意文件类型)
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
// 设置Content-Disposition告诉服务器这是文件附件
headers.set("Content-Disposition", "attachment; filename=\"" + filename + "\"");
// 4. 封装请求实体(包含文件内容和请求头)
HttpEntity<byte[]> request = new HttpEntity<>(fileBytes, headers);
// 5. 拼接完整的文件上传URL
// 注意:serverUploadPath应该是类成员变量,表示服务器存储路径
url = serverUploadPath + "/" + filename;
// 6. 执行PUT请求上传文件
// 问题点:这里直接使用put()方法无法获取响应状态,建议改用exchange()方法
restTemplate.put(url, request);
// 7. 返回文件路径(这里无法确认是否真正上传成功)
return url;
}
}
本文介绍了一个使用Java实现的文件上传帮助类,该类利用了Jersey API进行文件的远程上传。具体包括如何将字节数组转换为文件并上传至指定路径,同时确保目标路径存在。此外,还提供了必要的Maven依赖项。
1746

被折叠的 条评论
为什么被折叠?



