Java后端接收MultipartFile类型文件接口问题(带参与不带参)
后端接收不含参数的MultipartFile,接口处理该类型,实现层获取原始文件名拼接目标路径,通过FileOutputStream和IOUtils.copy写入文件,需注意路径正确、文件存在及IOException异常处理。
从后端接收前端的文件(不带参数)
先看一个最常见的场景:前端上传一个文件,后端直接拿过来存了。接口定义很简单,就是接收一个 MultipartFile 参数,然后返回一个字符串。实现层的逻辑也很直白——先把文件路径定好,从 MultipartFile 里取出原始文件名,然后拼成目标文件路径,最后通过 FileOutputStream 配合 IOUtils.copy 把流写进去。这里面有几个细节值得留意:如果文件保存失败,排查方向一般就是路径是否正确、文件是否已存在,或者干脆就是 IOException 没有处理好。日志里那句 uploaded a file successfully 虽然看起来随意,但在调试阶段非常有用。
public interface TestService {
String uploadFileTest(MultipartFile zipFile);
}
---------------------------------------------------------------------
@Service
public class TestServiceImpl implements TestService {
private static final Logger logger = LoggerFactory.getLogger(TestServiceImpl.class);
@Override
public String uploadFileTest(MultipartFile zipFile) {
// 文件保存路径
String targetFilePath = "D:\\360_js";
// 获取上传文件的文件名
String fileName = zipFile.getOriginalFilename();
// 真正地进行文件保存
File targetFile = new File(targetFilePath + File.separator + fileName);
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(targetFile);
IOUtils.copy(zipFile.getInputStream(), fileOutputStream);
logger.info("------>>>>>>uploaded a file successfully!<<<<<<------");
} catch (IOException e) {
e.printStackTrace();
return "IO异常";
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
logger.error("", e);
}
}
return "success";
}
}
-----------------------------------------------------------------
@Autowired
private TestService testService;
@PostMapping("/upload")
public String uploadFileTest(@RequestParam("uploadFile") MultipartFile zipFile) {
return testService.uploadFileTest(zipFile);
}
后端接收文件以及接收多个参数
但实际项目中,往往不只是传一个文件,还要附带其他参数。比如文件名称、保存路径、甚至业务ID。一个很自然的做法是把文件定义成实体类的一个属性,同时把其他参数也丢进同一个实体里,这样前端只需传一个对象就能搞定所有信息。来看具体实现:
// 实体类 entity FileSa veReqVO.ja va
@ApiModelProperty(value = "上传的文件", required = true)
@NotNull(message = "上传文件不能为空")
private MultipartFile file;
@ApiModelProperty(value = "文件名称",hidden = true)
private String Name;
@ApiModelProperty(value = "文件地址", hidden = true)
private String Url;
---------------------------------------------------------
// 接口 interface
void sa ve(FileSa veReqVO reqVO);
// impl层
@Service
public class KettleTransFileServiceImpl implements IKettleTransFileService {
private String path = "D:\\360_js";
@Autowired
private FileMapper fileMapper;
@Override
public void sa ve(FileSa veReqVO reqVO) {
try {
String fileName = reqVO.getFile().getOriginalFilename();
File destFile = new File(kettleHomePath + File.separator + fileName);
reqVO.getFile().transferTo(destFile);
} catch (IOException e) {
throw WinExceptionUtil.winException(SchExceptionEnum.SA VE_KETTLE_FILE_ERROR, reqVO.getName());
}
reqVO.setName(fileName);
reqVO.setUrl(path+ fileName);
fileMapper.sa ve(reqVO);
}
}
// controller层
@PostMapping("/sa ve")
public String sa ve(FileSa veReqVO reqVO) {
fileService.sa ve(reqVO);
return "添加成功";
}
使用 Postman 测试时,记得把请求类型改成 multipart/form-data,文件参数用 file,其他参数可以按需自行添加。这里也放一下关键的图片参考:

当然,实践中也有不少团队习惯把文件和参数分开定义——一个实体专门存放参数,然后接口里再单独传一个 MultipartFile 文件。比如这样:
public void updateFile(Entity entity, MultipartFile file) {
......
}
两种方式各有适用场景,关键看项目规范和接口复杂程度。如果参数较多,把文件塞进实体里会更简洁;如果只是单个文件加一两个参数,分开写可能更直观。
Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。
极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。
















