基于SpringMVC的文件上传下载功能

来源:互联网 发布:分类预测类算法 编辑:程序博客网 时间:2024/06/01 18:28

    • 前言
    • 配置
      • webxml
      • Spring MVC 配置
      • 通过注解配置Bean
    • 具体实现

前言

在开发网站时有时候我们需要对一些文件的上传和下载,下面提供一种基于SpringMVC的文件上传和下载Demo。

配置

这里只介绍单纯的SpringMVC的配置,对于Spring与SpringMVC之间的整合以下配置不做介绍。

web.xml

SpringMVC的配置主要是通过servlet实现的,基于Java的Web项目大部分是通过Servlet实现的,通过web.xml来实现对servlet的管理。
有Spring基础的同学应该都知道,Spring的上下文是通过Listener来读取并且实例化Bean的。而web.xml的执行顺序是按以下顺序执行的。
- context-param
- listener
- filter
- servlet
而Spring是由Listener来进行容器的初始化的,而SpringMVC是由servlet进行初始化的。
了解这个知识对项目的管理有一定的帮助,下面是web.xml的配置。

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns="http://xmlns.jcp.org/xml/ns/javaee"    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"    metadata-complete="true" version="3.1">    <servlet>        <servlet-name>springMVC</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <init-param>            <param-name>contextConfigLocation</param-name>            <param-value>classpath:spring-mvc.xml</param-value>        </init-param>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>springMVC</servlet-name>        <url-pattern>/</url-pattern>    </servlet-mapping>    <welcome-file-list>        <welcome-file>index.jsp</welcome-file>    </welcome-file-list></web-app>

Spring MVC 配置

下面是关于SpringMVC的配置,如spring-mvc.xml所示。

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc"    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context.xsd        http://www.springframework.org/schema/mvc        http://www.springframework.org/schema/mvc/spring-mvc.xsd">    <mvc:annotation-driven />    <!-- The base package need to be scan -->    <context:component-scan base-package="com.johnson.spring.mvc.file" /></beans>

通过注解配置Bean

这里使用了注解代替xml配置的方式实现SpringMVC相关Bean的配置。
下面是通过@Configure注解对Bean进行实例化。

package com.johnson.spring.mvc.file.configure;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.multipart.MultipartResolver;import org.springframework.web.multipart.commons.CommonsMultipartResolver;import org.springframework.web.servlet.ViewResolver;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import org.springframework.web.servlet.view.InternalResourceViewResolver;@Configuration@EnableWebMvcpublic class MvcConfigure extends WebMvcConfigurerAdapter {    @Bean    public ViewResolver resourceViewResolver() {        InternalResourceViewResolver resolver = new InternalResourceViewResolver();        resolver.setPrefix("/WEB-INF/page/");        resolver.setSuffix(".jsp");        return resolver;    }    @Bean    public MultipartResolver multipartResolver() {        CommonsMultipartResolver resolver = new CommonsMultipartResolver();        resolver.setDefaultEncoding("utf-8");        resolver.setMaxUploadSize(100000L);        resolver.setMaxInMemorySize(40960);        return resolver;    }    @Override    public void addResourceHandlers(final ResourceHandlerRegistry registry) {        registry.addResourceHandler("/**/*").addResourceLocations("/WEB-INF/frameworks/");    }}

具体实现

这样就完成了对于静态文件的访问、视图解析和文件解析这三个功能的配置了。接下来就可以通过@Controller配置进行web项目接口的实现了。具体由以下代码实现。使用了两种方式进行文件的上传和下载。推荐使用RequestEntity和MultipartFile的方式进行文件的上传和下载。如果在MvcConfigure中对MultipartResolver 实例化的话,在使用HttpServletRequest的方式来进行文件的上传时不需要使用CommonsMultipartResolver.resolveMultipart(request)进行转换,直接强制转换就可以了。

package com.johnson.spring.mvc.file.controller;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import java.util.Iterator;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.http.HttpHeaders;import org.springframework.http.HttpStatus;import org.springframework.http.MediaType;import org.springframework.http.ResponseEntity;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.multipart.MultipartFile;import org.springframework.web.multipart.MultipartHttpServletRequest;import org.springframework.web.multipart.commons.CommonsMultipartResolver;import com.johnson.common.util.FileUtil;@Controller@RequestMapping("/file")public class FileMvcController {    private static final String DOWNLOAD_FILE_NAME = "download/Download.txt";    private static final String UPLOAD_DIR = "upload";    private final String PATH = getFilePath();    @RequestMapping()    public String index() {        return "file";    }    @RequestMapping(value = "/request-entity", method = RequestMethod.POST)    public ResponseEntity<byte[]> downloadByte() throws UnsupportedEncodingException, FileNotFoundException {        HttpHeaders headers = new HttpHeaders();        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);        headers.setContentDispositionFormData("attachment", "download.txt");        String downloadFile = FileUtil.read(PATH, DOWNLOAD_FILE_NAME);        return new ResponseEntity<>(downloadFile.getBytes(), headers, HttpStatus.OK);    }    @RequestMapping(value = "/servlet-download", method = RequestMethod.POST)    public void downloadFile(HttpServletRequest request, HttpServletResponse response) throws IOException {        response.setContentType("application/octet-stream");// 设置强制下载不打开        response.addHeader("Content-Disposition", "attachment;fileName=" + "download.txt");        String downloadFile = FileUtil.read(PATH, DOWNLOAD_FILE_NAME);        OutputStream os = response.getOutputStream();        os.write(downloadFile.getBytes());        os.flush();        os.close();    }    @RequestMapping(value = "/servlet-upload", method = RequestMethod.POST)    public void uploadFile(HttpServletRequest request, HttpServletResponse response)            throws IllegalStateException, IOException {        // 在MvcConfigure中实例化了bean        CommonsMultipartResolver resolver = new CommonsMultipartResolver(                request.getSession().getServletContext());        resolver.setDefaultEncoding("utf-8");        resolver.setMaxUploadSize(100000L);        resolver.setMaxInMemorySize(40960);        // 判断是否包含文件        if (resolver.isMultipart(request)) {            // 将request转换为MultipartHttpServletRequest            // 在MvcConfigure实例化CommonsMultipartResolver之后,直接强制转换就可以了            // MultipartHttpServletRequest multiRequest = resolver.resolveMultipart(request);            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;            // 得到文件名列表的迭代器            Iterator<String> fileNameIterator = multiRequest.getFileNames();            while (fileNameIterator.hasNext()) {                // 根据表单内的name获取MultipartFile                MultipartFile file = multiRequest.getFile(fileNameIterator.next());                if (file != null) {                    // 获取文件名                    String fileName = file.getOriginalFilename();                    if (fileName.trim() != "") {                        // 获取存储路径                        String path = PATH + File.separator + UPLOAD_DIR + File.separator + fileName;                        File localFile = new File(path);                        if (!localFile.exists() || localFile.isDirectory()) {                            localFile.createNewFile();                        }                        // 写入文件                        file.transferTo(localFile);                    }                }            }        }    }    @RequestMapping("/multipart-file")    public void uploadFile(MultipartFile[] multipartfile) {        for (MultipartFile file : multipartfile) {            if (!file.isEmpty()) {                try {                    File dir = new File(PATH + File.separator + UPLOAD_DIR);                    if (!dir.exists()) {                        dir.mkdirs();                    }                    // 拿到输出流,同时重命名上传的文件                    FileOutputStream os = new FileOutputStream(                            PATH + File.separator + UPLOAD_DIR + File.separator + file.getOriginalFilename());                    // 拿到上传文件的输入流                    InputStream in = file.getInputStream();                    // 以写字节的方式写文件                    int b = 0;                    while ((b = in.read()) != -1) {                        os.write(b);                    }                    os.flush();                    os.close();                    in.close();                } catch (Exception e) {                    e.printStackTrace();                }            }        }    }    private String getFilePath() {        String classpath = this.getClass().getResource("/").getPath();        File file = new File(classpath);        String webInfoPath = file.getParent();        String filePath = webInfoPath + File.separator + "file";        return filePath;    }}

以上代码只是个简单的demo,仅供参考。
具体项目可以查看我的github地址:johnson.project

原创粉丝点击