文件上传下载(POST请求)

本文介绍了Java实现文件上传和下载的方法,包括所需的jar包配置、服务层处理、实体类设计以及监听。在文件上传时强调了避免使用特殊字符,并提供了相关博客链接。文件下载部分提到使用Postman测试可能出现中文乱码的问题,建议通过浏览器进行测试。最后,作者欢迎大家提供优化建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文件的上传

所需要的jar包:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.6</version>
</dependency> 

YML文件中的配置:

Spring:
    servlet:
      multipart:
          max-request-size: 10M
          max-file-size: 10M
corrosion:
   url: 请求路径

service

@Service
public class Dom{

    private final String ID_NAME = "编号";

    @Value("${corrosion.url}")
    private String url;

    @Override
    public T importFile(MultipartFile file) throws Exception {
        T respM01 = new T();
        ArrayList<DomF04RespS01> list = new ArrayList<>();
        String oldfilename = serviceFile.getOriginalFilename();//旧的文件名
        String substring = oldfilename.substring(oldfilename.lastIndexOf("."));
        String documentname = oldfilename.split(substring )[0];
        String replaceAll = UUID.randomUUID().toString().replaceAll("_", "");//UUID
        String newfilename = documentname + "SMDM" + replaceAll + substring; //新的文件名
        //这里的SMDM(神秘代码)没有任何意义,只是为了下载的时候好处理文件名
        String savePath = url + newfilename;//文件路径
        File file = new File(savePath);
        //判断保存地址的文件夹是否存在,不存在就新建
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        //这里是一个内部类监听,可以拿出来单独写一份。监听用来处理数据
        AnalysisEventListener<K> eventListener = new AnalysisEventListener<>() {
            private final Logger log =             
                            LoggerFactory.getLogger(AnalysisEventListener.class);
            @Override
            public void invoke(K k, AnalysisContext analysisContext) {
                //这里边就是你要处理的数据,因情况而定
                //k就是你要处理的数据
                if(k.getId() != null){
                    list.add(k);
                }
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {

            }
        };

        InputStream in = serviceFile.getInputStream();
        EasyExcel.read(in, K.class, eventListener).sheet().doRead();
        respM01.setDemoList(list);
        //别忘记关闭
        in.close();
        return respM01;
    }
}

这里有一个小知识点,文件名命名的时候最好不要出现这些符号。一是没有意义,二是处理也不方便,具体还是看这位大佬的博客

http请求中对特殊字符的处理_forwardMyLife的博客-优快云博客_http特殊字符

实体类

@Data
public class dom implements Serializable{

    private static final long serialVersionUID = 1495675280489558317L;

    /**
     * 编号
     */
    @ExcelProperty(value = "编号",index = 0)
    private String id;

    /**
     * 阶段及任务
     */
    @ExcelProperty(value = "阶段及任务",index = 1)
    private String stage;

    /**
     * 工时
     */
    @ExcelProperty(value = "工时",index = 2)
    private String workingHours;

    /**
     * 备注
     */
    @ExcelProperty(value = "备注",index = 3)
    private String remarks;

}

实体类中的数据要对应到你的表格中去,尽量按循序来

@ExcelProperty(value = "对应到表格中的文字",index = 表格的位置)

如果你是按照循序来的,你大可以不需要index

文件的下载

collection

@ApiOperation("文件下载")
@GetMapping("/bom/download")
public T download(String path,HttpServletResponse response) throws Exception {
    //这里我把response和path封装了起来
    //我在往业务层传递的时候response老是传递不过去
    T ReqtM01 = new T();
    ReqtM01.setPath(path);
    ReqtM01.setResponse(response);
    return domDownload.dom(ReqtM01);
}

业务层

@Service
public class dom{

    @Value("${corrosion.url}")
    private String url;

    private final Integer RETURN_CODE = 200;

    @Override
    public Integer execute(T t) throws Exception {
        String oldfilename =  t.getPath()
        String path = url + oldfilename;//文件路径
        HttpServletResponse response = t.getResponse();
        // 设置response的Header
        response.setCharacterEncoding("UTF-8");
        // 下载的文件的路径(绝对路径)
        File file = new File(path);
        // 获取文件名
        String filename = file.getName();
        // 获取文件的后缀名
        String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
        //新的名字
        String newfilename = filename.split("SMDM")[0] + "." + ext;
        // 将文件写入输入流
        FileInputStream fileInputStream = new FileInputStream(file);
        InputStream fis = new BufferedInputStream(fileInputStream);
        byte[] buffer = new byte[fis.available()];
        fis.read(buffer);
        fis.close();
        // 清空response
        response.reset();
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(newfilename, "UTF-8"));
        // 告知浏览器文件的大小
        response.addHeader("Content-Length", "" + file.length());
        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        response.setContentType("application/octet-stream");
        outputStream.write(buffer);
        outputStream.flush();
        return RETURN_CODE;
    }
}

文件下载使用postman时要注意,中文名会乱码所以测试下载的时候最好还是使用浏览器测试
也可能是因为我操作不当才导致postman中文乱码问题,具体问题还是要自行百度

监听

public class ExcelListener extends AnalysisEventListener<> {
    private final Logger log = LoggerFactory.getLogger(ExcelListener.class);

    private static final int BATCH_COUNT = 5;

    private List<T> datas = Lists.newArrayList();

    @Override
    public void invoke(T t, AnalysisContext analysisContext) {
        log.info("解析到一条数据:{}", JSON.toJSONString(t));
        //数据存储到list,
        datas.add(t);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        saveData();
        // 存储完成清理 list
        datas.clear();
        if (datas.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            datas.clear();
        }
        //要是想一次性取出数据,注解掉这一块代码自己写处理逻辑

    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveData();
        LOGGER.info("所有数据解析完成!");
    }

    /**
     * 入库
     */
    private void saveData() {
        log.info("{}条数据,开始存储数据库!", datas.size());
        //这个方法自己实现  能完成保存数据入库即可
        //demoDAO.save(datas);
        LOGGER.info("存储数据库成功!");
    }

    public List<DomF04RespS01> getDatas() {
        return datas;
    }

    public void setDatas(List<DomF04RespS01> datas) {
        this.datas = datas;
    }
}


小白见解,有需要优化或者不对的地方还请大家不吝赐教

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值