SpringBoot实现文件上传下载的功能

简介: SpringBoot我们大多数的时候是当做服务提供者来使用的,但是在一些场景中还是要用到一些文件上传下载这种"非常规"操作的。那么怎么在SpringBoot中实现文件的上传下载功能呢?想象一些我们在SpringMVC中是怎么做的。
SpringBoot我们大多数的时候是当做服务提供者来使用的,但是在一些场景中还是要用到一些文件上传下载这种"非常规"操作的。那么怎么在SpringBoot中实现文件的上传下载功能呢?想象一些我们在SpringMVC中是怎么做的。我们需要在SpringMVC的配置文件中增加文件上传的Bean的配置,如下:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

然后在后台对应的处理方法中就可以直接获取到文件的输入流了。而对于SpringBoot来说,我们不需要配置文件上传的解析类了,因为SpringBoot已经帮我们注册好了。下面我们来看一下具体的开发。

增加thymeleaf的依赖

这里我们用thymeleaf来作为页面的呈现,所以我们这里需要引入thymeleaf的相关依赖:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

文件上传下载页面:

接着我们需要写一个文件的上传下载的页面,我简单的写了下面这个页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
    <script th:src="@{/js/jquery-2.1.4.min.js}"></script>
</head>
<body>
<form id="upload" enctype="multipart/form-data" method="post" action="/uploadAndDownload/uploadFileAction">
    <input type="file" name="uploadFile"/>
    <input type="hidden" name="id" value="12"/>
    <input type="button" value="文件上传" onclick="doUpload()"/>
</form>
<input type="button" value="下载文件" onclick="doDownload()"/>
<form id="download" method="post" action="/uploadAndDownload/downloadFileAction">
</form>
<script type="text/javascript">
    function doUpload() {
        var upl = document.getElementById("upload");
        upl.submit();
    }
    function doDownload() {
        var upl = document.getElementById("download");
        upl.submit();
    }
</script>
</body>
</html>

后台处理类:

接着我们写一个处理文件上传和下载的控制类:

访问页面的方法:

@Controller
@RequestMapping("/uploadAndDownload")
public class UploadAndDownloadFileController {

    @RequestMapping("/index")
    public String index() {

        return "uploadAndDownload";
    }

}

上传文件的处理方法:

    @RequestMapping(value = "/uploadFileAction", method = RequestMethod.POST)
    public ModelAndView uploadFileAction(@RequestParam("uploadFile") MultipartFile uploadFile, @RequestParam("id") Long id) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("uploadAndDownload");
        InputStream fis = null;
        OutputStream outputStream = null;
        try {
            fis = uploadFile.getInputStream();
            outputStream = new FileOutputStream("G:\\uploadfile\\"+uploadFile.getOriginalFilename());
            IOUtils.copy(fis,outputStream);
            modelAndView.addObject("sucess", "上传成功");
            return modelAndView;
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        modelAndView.addObject("sucess", "上传失败!");
        return modelAndView;
    }

下载文件的处理方法:

    @RequestMapping("downloadFileAction")
    public void downloadFileAction(HttpServletRequest request, HttpServletResponse response) {

        response.setCharacterEncoding(request.getCharacterEncoding());
        response.setContentType("application/octet-stream");
        FileInputStream fis = null;
        try {
            File file = new File("G:\\config.ini");
            fis = new FileInputStream(file);
            response.setHeader("Content-Disposition", "attachment; filename="+file.getName());
            IOUtils.copy(fis,response.getOutputStream());
            response.flushBuffer();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
当我们发送请求为:http://localhost:8003/uploadAndDownload/index,会看到如下的页面(没有做排版处理):
当我们上传文件时,会调用uploadFileAction这个方法,然后将上传的文件信息存放到一个地方,根据个人的需求去做。
当我们下载文件时:

有时候我们可能需要限制上传文件的大小,可以这样设置上传文件的大小:
@Configuration
public class UploadFileConfiguration {

    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        factory.setMaxFileSize("256KB");
        factory.setMaxRequestSize("512KB");
        return factory.createMultipartConfig();
    }
}

有时候我们可能还要进行一些文件类型的现在,那么这个怎么做呢?我们可以通过自定的Interceptor来实现这样的功能。代码示例如下:

自定义的拦截器

package com.zkn.learnspringboot.aop;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * Created by zkn
 */
@Component("fileUploadInterceptor")
@ConfigurationProperties(prefix = "fileupload")
public class FileUploadInterceptor extends HandlerInterceptorAdapter {

    private List<String> allowFileTypeList;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        //文件上传的Servlet
        if (request instanceof MultipartHttpServletRequest) {
            //允许所有的文件类型
            if (allowFileTypeList == null) {
                return super.preHandle(request, response, handler);
            }
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Iterator<String> it = multipartRequest.getFileNames();
            if (it != null) {
                while (it.hasNext()) {
                    String fileParameter = it.next();
                    List<MultipartFile> listFile = multipartRequest.getFiles(fileParameter);
                    if (!CollectionUtils.isEmpty(listFile)) {
                        MultipartFile multipartFile = null;
                        String fileName = "";
                        for (int i = 0; i < listFile.size(); i++) {
                            multipartFile = listFile.get(i);
                            fileName = multipartFile.getOriginalFilename();
                            int flag = 0;
                            if ((flag = fileName.lastIndexOf(".")) > 0) {
                                fileName = fileName.substring(flag+1);
                            }
                            //不被允许的后缀名
                            if (!allowFileTypeList.contains(fileName)) {
                                this.outputStream(request, response);
                                return false;
                            }
                        }
                    }
                }
            }
        }
        return super.preHandle(request, response, handler);
    }

    private void outputStream(HttpServletRequest request, HttpServletResponse response) {
        response.setCharacterEncoding(request.getCharacterEncoding());
        ServletOutputStream output = null;
        try {
            output = response.getOutputStream();
            output.write(("所传入的文件类型是不被允许的,允许的文件类型是:" + Arrays.toString(allowFileTypeList.toArray())).getBytes(request.getCharacterEncoding()));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void setAllowFileType(String allowFileType) {
        //默认运行所有的类型
        if (StringUtils.isEmpty(allowFileType)) {
            allowFileTypeList = null;
            return;
        }
        allowFileTypeList = Arrays.asList(allowFileType.split(","));
    }

}

注册拦截器:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private FileUploadInterceptor fileUploadInterceptor;
    //注册拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(fileUploadInterceptor);
    }
    //配置加载静态资源
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        registry.addResourceHandler("/templates/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX+"/templates/");
        registry.addResourceHandler("/static/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX+"/static/");
        super.addResourceHandlers(registry);
    }
}
新增配置信息:
fileupload.allowFileType=txt,docs
这样我们的程序在运行的时候就会把不是txt或者docs文件类型的文件给过滤掉。

相关文章
|
4天前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
65 2
|
3月前
|
缓存 前端开发 Java
SpringBoot 实现动态菜单功能完整指南
本文介绍了一个动态菜单系统的实现方案,涵盖数据库设计、SpringBoot后端实现、Vue前端展示及权限控制等内容,适用于中后台系统的权限管理。
255 1
|
5月前
|
安全 Java API
Spring Boot 功能模块全解析:构建现代Java应用的技术图谱
Spring Boot不是一个单一的工具,而是一个由众多功能模块组成的生态系统。这些模块可以根据应用需求灵活组合,构建从简单的REST API到复杂的微服务系统,再到现代的AI驱动应用。
|
4月前
|
监控 安全 Java
Java 开发中基于 Spring Boot 3.2 框架集成 MQTT 5.0 协议实现消息推送与订阅功能的技术方案解析
本文介绍基于Spring Boot 3.2集成MQTT 5.0的消息推送与订阅技术方案,涵盖核心技术栈选型(Spring Boot、Eclipse Paho、HiveMQ)、项目搭建与配置、消息发布与订阅服务实现,以及在智能家居控制系统中的应用实例。同时,详细探讨了安全增强(TLS/SSL)、性能优化(异步处理与背压控制)、测试监控及生产环境部署方案,为构建高可用、高性能的消息通信系统提供全面指导。附资源下载链接:[https://pan.quark.cn/s/14fcf913bae6](https://pan.quark.cn/s/14fcf913bae6)。
623 0
|
18天前
|
Java 数据库连接 应用服务中间件
基于springboot的母婴健康交流系统
本平台旨在为新手父母提供专业、系统的婴幼儿健康知识与交流空间,整合权威资源,解决育儿信息碎片化与误导问题,支持经验分享与情感互助,助力科学育儿。
|
3天前
|
搜索推荐 JavaScript Java
基于springboot的儿童家长教育能力提升学习系统
本系统聚焦儿童家长教育能力提升,针对家庭教育中理念混乱、时间不足、个性化服务缺失等问题,构建科学、系统、个性化的在线学习平台。融合Spring Boot、Vue等先进技术,整合优质教育资源,提供高效便捷的学习路径,助力家长掌握科学育儿方法,促进儿童全面健康发展,推动家庭和谐与社会进步。
|
3天前
|
JavaScript Java 关系型数据库
基于springboot的古树名木保护管理系统
本研究针对古树保护面临的严峻挑战,构建基于Java、Vue、MySQL与Spring Boot技术的信息化管理系统,实现古树资源的动态监测、数据管理与科学保护,推动生态、文化与经济可持续发展。
|
16天前
|
JavaScript Java 关系型数据库
基于springboot的电影购票管理系统
本系统基于Spring Boot框架,结合Vue、Java与MySQL技术,实现电影信息管理、在线选座、购票支付等核心功能,提升观众购票体验与影院管理效率,推动电影产业数字化发展。
|
19天前
|
JavaScript Java 关系型数据库
基于springboot的家政服务预约系统
随着社会节奏加快与老龄化加剧,家政服务需求激增,但传统模式存在信息不对称、服务不规范等问题。基于Spring Boot、Vue、MySQL等技术构建的家政预约系统,实现服务线上化、标准化与智能化,提升用户体验与行业效率,推动家政服务向信息化、规范化发展。