如何使用Javax库接收Multipart格式POST请求中的文件?
解决方案
一、前端代码修正
前端存在3个关键错误,导致后端无法正确解析请求:
mode: 'no-cors'限制:该模式会让浏览器屏蔽响应,且禁止自定义部分请求头,直接移除即可- 错误的
Content-Type设置:form/multipart是错误的MIME类型,正确的是multipart/form-data,且不需要手动设置——浏览器会自动添加包含boundary的Content-Type头,手动设置会丢失boundary,导致后端无法解析 - 错误的请求头:
Access-Control-Allow-Origin是服务器响应头,前端不需要在请求中设置
修正后的前端代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <input type="file" onchange="handler(this.files[0])" /> <script type="text/javascript"> const handler = (file) => { const formData = new FormData(); // 固定键名"file",方便后端统一获取 formData.append("file", file); const requestOptions = { method: 'POST', body: formData }; fetch(`http://localhost:8800/files/setVideo`, requestOptions) .then(response => response.json()) .then(data => console.log(data)) .catch(err => console.log(err)) }; </script> </body> </html>
二、后端正确实现
在Java EE的JAX-RS环境中,推荐使用@FormDataParam来接收multipart文件,以下是完整修正方案:
1. 引入Multipart依赖(如果未引入)
如果使用Jersey作为JAX-RS实现,添加Maven依赖:
<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-multipart</artifactId> <version>你的Jersey版本(比如2.39.1)</version> </dependency>
2. 修正控制器方法
- 使用
@FormDataParam("file")绑定前端FormData中的文件部分(键名要和前端append的一致) - 通过
Part.getSubmittedFileName()获取原文件名,不需要自定义extractFileName方法 - 确保临时目录存在,避免文件写入失败
修正后的后端代码:
import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import javax.ws.rs.POST; import javax.ws.rs.Produces; import javax.ws.rs.Consumes; import javax.ws.rs.Path; import javax.ws.rs.core.MediaType; import javax.json.JsonObject; import javax.json.Json; import javax.servlet.ServletException; import javax.servlet.http.Part; import org.glassfish.jersey.media.multipart.FormDataParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.UriInfo; @Path("files") public class FilesWork{ @Context private UriInfo context; @POST @Path(value = "/setVideo") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_JSON) public String UploadFileToCloud(@FormDataParam("file") Part part) throws IOException, ServletException { String tempFilePath = "/tempFiles"; // 确保临时目录存在 File tempDir = new File(tempFilePath); if (!tempDir.exists()) { tempDir.mkdirs(); } // 获取原文件名 String fileName = part.getSubmittedFileName(); File tempFile = new File(tempDir, fileName); // 将文件流写入临时文件 try (InputStream fileStream = part.getInputStream()) { Files.copy(fileStream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING); } AWSUtils s3 = new AWSUtils(); // 这里调用AWS上传逻辑,比如s3.uploadFile(tempFile, fileName); JsonObject urlBuilder = Json.createObjectBuilder().add("Link", "上传后的AWS链接").build(); return FunctionsGlobal.returnDataAll(urlBuilder); } }
替代方案:不依赖Multipart扩展
如果不想引入额外依赖,可以通过注入HttpServletRequest获取文件:
// 导入HttpServletRequest import javax.servlet.http.HttpServletRequest; @POST @Path(value = "/setVideo") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_JSON) public String UploadFileToCloud(@Context HttpServletRequest request) throws IOException, ServletException { Part part = request.getPart("file"); // 后续逻辑和上面一致 }
内容的提问来源于stack exchange,提问作者dvaschenko
相关产品推荐
相关产品推荐

