You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot MVC实现对象序列化下载及反序列化上传问题求解

Spring Boot MVC 实现Java序列化文件导出/导入完整方案

Web场景下不要沿用本地Java程序写死磁盘路径的序列化逻辑,服务端无法直接操作用户本地磁盘,序列化/反序列化逻辑直接对接HTTP请求/响应的IO流即可,不需要在服务端磁盘生成临时文件。


1. 前置准备

确保需要序列化的实体类实现Serializable接口,固定序列化版本号,避免后续类结构修改导致旧文件反序列化失败:

import java.io.Serializable;

public class SavedGame implements Serializable {
    // 固定版本号,不要随意修改
    private static final long serialVersionUID = 1L;
    
    private String info1;
    private String info2;
    private String info3;

    public SavedGame(String info1, String info2, String info3) {
        this.info1 = info1;
        this.info2 = info2;
        this.info3 = info3;
    }

    // 自行补充getter、setter
}

2. 功能一:序列化对象导出到用户本地

点击按钮触发下载时,浏览器会自动弹出本地路径保存窗口,用户选择路径后文件会直接存入对应位置。

后端接口实现

直接把序列化输出流对接HTTP响应的输出流,设置下载响应头即可:

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.ObjectOutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

@RestController
public class SerializeController {

    @GetMapping("/export/save")
    public void exportSavedGame(HttpServletResponse response) throws Exception {
        // 替换为你实际业务中需要序列化的对象
        SavedGame savedGame = new SavedGame("存档1", "进度80%", "道具全收集");

        // 设置响应头,告知浏览器当前响应是文件下载请求
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        String fileName = URLEncoder.encode("game_save.ser", StandardCharsets.UTF_8);
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
        response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);

        // 序列化逻辑直接对接响应输出流,不需要写入服务端本地磁盘
        try (ObjectOutputStream oos = new ObjectOutputStream(response.getOutputStream())) {
            oos.writeObject(savedGame);
            oos.flush();
        }
    }
}

前端代码

不需要复杂逻辑,按钮点击直接访问下载接口即可:

<button id="exportBtn" class="primary">导出存档文件</button>

<script>
document.getElementById('exportBtn').addEventListener('click', () => {
    window.location.href = '/export/save';
});
</script>

3. 功能二:上传本地序列化文件反序列化为对象

后端接口实现

直接读取上传文件的输入流做反序列化,不需要把上传文件保存到服务端磁盘:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.io.ObjectInputStream;

// 可和上面的导出方法放在同一个Controller中
@PostMapping("/import/save")
public String importSavedGame(@RequestParam("file") MultipartFile file) throws Exception {
    // 基础格式校验
    String originalFilename = file.getOriginalFilename();
    if (originalFilename == null || !originalFilename.endsWith(".ser")) {
        return "文件格式错误,请上传.ser格式的存档文件";
    }

    // 直接从上传流反序列化
    try (ObjectInputStream ois = new ObjectInputStream(file.getInputStream())) {
        SavedGame savedGame = (SavedGame) ois.readObject();
        // 这里写拿到对象后的业务逻辑:存库、更新内存状态等
        System.out.println("导入存档成功:" + savedGame.getInfo1());
        return "存档导入成功";
    } catch (ClassCastException e) {
        return "文件内容不合法,不是有效存档文件";
    }
}

前端代码

基于你提供的表单改造,拦截默认提交行为,用FormData上传文件即可:

<form id="singleUploadForm" name="singleUploadForm">
     <input id="singleFileUploadInput" type="file" name="file" class="file-input" accept=".ser" required />
     <button type="submit" class="primary submit-btn">导入存档</button>
</form>

<script>
const form = document.getElementById('singleUploadForm');
form.addEventListener('submit', async (e) => {
    e.preventDefault();
    const file = document.getElementById('singleFileUploadInput').files[0];
    if (!file) {
        alert('请先选择要导入的文件');
        return;
    }
    const formData = new FormData();
    formData.append('file', file);

    const res = await fetch('/import/save', {
        method: 'POST',
        body: formData
    });
    alert(await res.text());
    form.reset();
});
</script>

补充配置

如果你的序列化文件大小超过Spring Boot默认的1MB上传限制,在application.properties中添加以下配置调整阈值:

spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

注意:不要对来源不可信的文件做反序列化操作,存在远程代码执行风险,公网接口建议额外增加文件签名、类白名单校验逻辑。

内容的提问来源于stack exchange,提问作者Vindie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 23:24:24