REST API开发异常:打开Word/PDF文件触发FileNotFoundException
嘿,这个坑我之前踩过!咱们先把问题说透:你现在通过Swagger传的是客户端本地的文件路径(比如Z:\Some\Path\To\My\File.docx),但后端根本没法直接访问客户端的本地文件系统啊!而且Spring的AbstractResource.getFile()方法在这里是在尝试把HTTP请求传来的输入流资源解析成服务器本地的文件路径,方向完全错了,所以才会抛出那个错误。
核心问题拆解
java.io.FileNotFoundException: InputStream resource [resource loaded through InputStream] cannot be resolved to absolute file path
这个错误的本质是:你后端拿到的资源是来自HTTP请求的输入流,不是服务器本地文件系统里的文件,自然不存在对应的绝对路径。就算你本地测试时服务器和客户端是同一台机器,这种方式在生产环境也完全行不通——总不能要求用户的文件路径和服务器的路径一致吧?
正确的解决方案:让前端上传文件而非路径
你需要把API接口改成接收文件上传,而不是字符串路径,具体步骤如下:
1. 修改Spring接口,接收MultipartFile参数
把原来接收路径的接口改成接收MultipartFile,这样前端可以直接上传文件的二进制内容,后端拿到输入流就能处理:
@PostMapping("/process-document") public ResponseEntity<String> processDocument(@RequestParam("document") MultipartFile file) { // 先判断文件是否为空 if (file.isEmpty()) { return ResponseEntity.badRequest().body("请选择要上传的文件"); } try (InputStream fileInputStream = file.getInputStream()) { // 这里写你的业务逻辑:比如用Apache POI解析Word,iText处理PDF // 示例:读取文件内容(仅做演示) byte[] content = fileInputStream.readAllBytes(); return ResponseEntity.ok("文件处理完成,文件大小:" + content.length + "字节"); } catch (IOException e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body("文件处理失败:" + e.getMessage()); } }
2. 在Swagger里测试上传
修改接口后,Swagger会自动识别MultipartFile参数,你只需要:
- 选择
form-data类型的请求 - 参数名填
document(和接口里的@RequestParam对应) - 参数类型选择
File - 点击"Choose File"选择本地的Word/PDF文件,然后发送请求就可以正常处理了
特殊场景:如果需要访问服务器本地文件
要是你的业务确实需要后端读取服务器自己本地的文件,那你应该传递服务器本地的绝对路径(比如Windows服务器的D:\ServerDocs\File.docx,或者Linux的/var/documents/File.pdf),同时要确保运行后端程序的用户有访问该路径的读写权限,这种情况下AbstractResource.getFile()就能正常解析路径了。
内容的提问来源于stack exchange,提问作者Nicolas HELIE

