文件上传的几种方式

本文详细介绍了在SpringMVC框架中实现文件上传和下载的方法。包括配置所需的依赖库,如Spring-web、Spring-webmvc、commons-io和commons-fileupload等。通过三种不同方式展示如何在控制器中处理文件上传,涉及MultipartFile、MultipartHttpServletRequest和数组形式的文件上传。同时,提供了文件下载的实现代码,展示了如何响应HTTP请求,设置文件头并读取文件流。

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

一、springmvc中的文件上传

1.配置文件

(1).pom文件,文件上传主要需要如下几个jar包

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.5</version>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>

(2)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">

    <!-- 开启包扫描 -->
    <context:component-scan base-package="controller"/>
    <!-- 设置配置方案-->
    <mvc:annotation-driven/>
    <!-- 视图解析器 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- 文件上传解析器:需要注意的是这个bean的id必须是multipartResolver才能被识别,否则会报没有配置该解析器的错误 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="utf-8"></property>
        <property name="maxUploadSize" value="10240000"/>
    </bean>
</beans>

(3)web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>uploadmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>uploadmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

2.编写控制类UploadController.java

第一种,单文件上传,使用MultipartFile作为方法参数接收传入的文件。

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

/**
 * @author: **
 * @date:2018/9/18 16:01
 * @description:
 */
@Controller
@RequestMapping("/test")
public class UploadController {

    //文件上传
    @RequestMapping("/upload")
    public String uploadfile(@RequestParam("file") MultipartFile multipartFile) throws IOException {

        if(!multipartFile.isEmpty()){
            //拼接你想存储的位置和文件名
            String path = "D:/test/"+multipartFile.getOriginalFilename();
            //获得项目路径即webapp所在路径,可选
            //String pathRoot = request.getSession().getServletContext().getRealPath("");
            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }
            try {
                multipartFile.transferTo(tempFile);
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

//这里除了transferTo方法,也可以用字节流的方式上传文件,但是字节流比较慢,所以还是建议用transferTo
//            try {
//                //获取输出流
//                OutputStream os=new FileOutputStream(path);
//                //获取输入流 CommonsMultipartFile 中可以直接得到文件的流
//                InputStream is=multipartFile.getInputStream();
//                byte[] buffer= new byte[1024];
//                int len = is.read(buffer);
//                while(len!=-1){
//                    os.write(buffer, 0, len);
//                }
//                os.flush();
//                os.close();
//                is.close();
//            } catch (FileNotFoundException e) {
//                // TODO Auto-generated catch block
//                e.printStackTrace();
//            }

        }

        //可以用ModelMap或者request请求域来返回上传路径
        //modelMap.addAttribute("fileUrl", path); 
        //或者request.setAttribute("fileUrl",path);
        return "success";
    }

    //上传成功页面
    @RequestMapping("/uploadpage")
    public String uploadpage(){
        return  "upload";
    }
}

第二种,单文件上传,利用MultipartHttpServletRequest来解析request中的文件

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;

/**
 * @author: ***
 * @date:2018/9/18 16:01
 * @description:
 */
@Controller
@RequestMapping("/test")
public class UploadController {

    @RequestMapping("/upload")
    public ModelMap upload(HttpServletRequest request, ModelMap model) {
        // 先实例化一个文件解析器
        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());

        // 判断request请求中是否有文件上传
        if (commonsMultipartResolver.isMultipart(request)) {
            // 转换request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            // 获得文件
            MultipartFile file = multiRequest.getFile("file");
            if (!file.isEmpty()) {
                //上传路径
                String path = "D:/test/"+file.getOriginalFilename();
                // 创建文件实例
                File tempFile = new File(path);
                if (!tempFile.exists()) {
                    tempFile.mkdir();
                }
                try {
                    //同样可以用流文件方式上传文件
                    file.transferTo(tempFile);
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //返回上传路径,方法一
                model.addAttribute("fileUrl", path);
                // 方法二:Request域属性
                // request.setAttribute("fileUrl", path);
            }
        }
        return model;
    }
}

第三种是多文件上传,传入参数是数组或者request,多文件只是需要将上传的单个文件从数组或者request中遍历出来,然后进行单文件上传操作。

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: ***
 * @date:2018/9/18 16:01
 * @description:
 */
@Controller
@RequestMapping("/test")
public class UploadController {

    /**
     * 多文件上传,方式一:利用MultipartFile[]作为方法的参数接收传入的文件
     *  用 transferTo方法来保存图片,保存到本地磁盘。
     * @author chunlynn
     */
    @RequestMapping("/upload")
    public ModelMap upload3(@RequestParam("file") MultipartFile[] files, ModelMap model) {
        List<String> fileUrlList = new ArrayList<String>(); //用来保存文件路径
        // 先判断文件files不为空
        if (files != null && files.length > 0) {
            for (MultipartFile file : files) { //循环遍历取出单个文件
                if (!file.isEmpty()) {
                    String fileName = file.getOriginalFilename();
                    String path = "D:/test/"+fileName;      //这里D:/test/可以修改为自己的路径,也可以对fileName进行修改。
                    // 创建文件实例
                    File tempFile = new File(path);
                    //判断父级文件夹是否存在
                    if (!tempFile.getParentFile().exists()) {
                        tempFile.getParentFile().mkdir();
                    }
                    if (!tempFile.exists()) {
                        tempFile.mkdir();
                    }
                    try {
                        //这里也可以用流实现
                        file.transferTo(tempFile);
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    fileUrlList.add(path);
                }
            }
            // 方法一:model属性保存图片路径
            model.addAttribute("fileUrlList", fileUrlList);
            // 方法二:request域属性保存图片路径
            // request.setAttribute("fileUrlList", fileUrlList);
        }
        return model;
    }



    /**
     * 多文件上传,方式二:利用MultipartHttpServletRequest来解析Request中的文件
     */
    @RequestMapping("/upload2")
    public ModelMap upload2(HttpServletRequest request,ModelMap model) {
        List<String> fileUrlList = new ArrayList<>(); //用来保存文件路径
        // 先实例化一个文件解析器
        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        // 判断request请求中是否有文件上传
        if (commonsMultipartResolver.isMultipart(request)) {
            // 转换Request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            // 获得文件,方式一
            List<MultipartFile> files = multiRequest.getFiles("file"); 
            for (MultipartFile file : files) { //循环遍历取出单个文件上传
                if (!file.isEmpty()) {
                    // 获得原始文件名,拼接需要上传的位置得到路径
                    String fileName = file.getOriginalFilename();
                    String path = "D:/test/"+fileName;

                    // 创建文件实例
                    File tempFile = new File(path); //文件保存路径为pathRoot + path
                    if (!tempFile.getParentFile().exists()) {
                        tempFile.getParentFile().mkdir();
                    }
                    if (!tempFile.exists()) {
                        tempFile.mkdir();
                    }
                    try {
                        //也可用流的方式上传
                        file.transferTo(tempFile);
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    fileUrlList.add(path);
                }
            }
            model.addAttribute("fileUrlList", fileUrlList); 
            // 方法二:request域属性保存
            // request.setAttribute("fileUrlList", fileUrlList);
        }
        return model;
    }
}

文件下载,在这里我是写死了文件的下载路径和下载文件名的,实际项目中,这两个字段下载路径一般会配置在配置文件中,下载文件的名称则是前台通过request传递到后台的,所以这个可以将这两个字段作为传入参数,写成接口。

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/**
 * @author: ***
 * @date:2018/9/18 16:01
 * @description:
 */
@Controller
@RequestMapping("/test")
public class UploadController {

     
    /* *
     * @description: 文件下载列表
     */
    @RequestMapping("/list")
    public ModelAndView getlist(){
        String path = "D:/test";
        File directory = new File(path);
        List list = new ArrayList();

        File[] files = directory.listFiles();
        for (File file:files) {
            if (file.isFile()){
                String filename = file.getName();
                list.add(filename);
            }

        }
        ModelMap modelMap = new ModelMap();
        modelMap.addAttribute("list",list);
        return new ModelAndView("list",modelMap);
    }
    /**
     * 文件下载功能
     * @param request,response
     * @throws Exception
     */
    @RequestMapping("/down")
    @ResponseBody
    public void down(HttpServletRequest request,HttpServletResponse response) throws Exception {
        try{
            String fileName = request.getParameter("filename");
            String path = "D:/test/" + fileName;
            File file = new File(path);
            //流的形式下载文件
            InputStream in = new BufferedInputStream(new FileInputStream(file));
            byte[] buffer = new byte[in.available()];
            in.read(buffer);
            in.close();
            //清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream os = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            os.write(buffer);
            os.flush();
            os.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

}

3.页面

upload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件上传页</title>
</head>
<body>
    <form action="/mvc/test/upload" method="post" enctype="multipart/form-data">
        <label>上传文件</label>
        <input type="file" name="file">
        <input type="submit" value="提交">
    </form>
</body>
</html>

注意,form表单里,enctype="multipart/form-data",一定要配置。action是你方法的访问路径,由于我在tomcat中配置了项目访问名称是mvc,所以我这里的路径会是“/mvc/test/upload”,具体路径由个人的配置而定。

还有个上传成功的提示页,自己写一个就行,不贴代码了。

list.jsp

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.*" %>
<% String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>
<html>
<head>
    <title>列表</title>
    <script type="text/javascript" src="<%=basePath%>js/jquery-1.8.3.min.js"></script>
</head>
<body>
<%
List<String> list1 = (List<String>) request.getAttribute("list");
    int i =1;
    for (String name:list1) {

        i++;
%>
<a href="/mvc/test/down/?filename=<%=name%>"><%=name%></a>
<%
    }
%>
</body>
</html>

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值