Spring MVC---文件上传及下载(六)

(一)文件上传概述

多数文件上传都是通过表单形式提交给后台服务器,因此要实现文件上传功能就需要提供一个文件上传的表单。表单必须满足以下3个条件:

1. form表单中的method属性设置为post

2.form表单中的enctype属性设置为multipart/form-data

注:multiple="multiple实现多文件上传
3. 提供<input id="file" type="file" name="uploadfile" multiple="multiple" />

1.在springmvc-config.xml中配置CommonsMultipartResolver

 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
         <!--设置文件上传编码-->
         <property name="defaultEncoding" value="UTF-8"/>
         <!--设置允许上传文件的最大值(2M))-->
         <property name="maxUploadSize" value="2097152"/>
         <!--设置缓存中的最大值(2M))-->
         <property name="maxInMemorySize" value="2097152"/>
         <!--设置文件推出解析-->
         <property name="resolveLazily" />
     </bean>

2.MultipartFile接口的主要方法

方法 说明
String getName() 获取多部件form表单的参数名
String getOriginalFilename() 获取上传文件名
String getContentType() 获取文件内容类型
boolean isEmpty() 判断上传文件是否为空
long getSize() 获取上传文件的大小
byte[] getBytes() 以字节数组的形式返回文件内容
InputStream getInputStream() 读取问价内容,返回一个InputStream对象
void transferTo(File dest) 将上传文件保存到目标目录

(二)文件上传演示

项目结构图:
这里写图片描述这里写图片描述

步骤如下:

1.spring-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
  http://www.springframework.org/schema/mvc
  http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
  http://www.springframework.org/schema/context 
  http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    <!-- 定义组件扫描器,指定需要扫描的包 -->
    <context:component-scan base-package="com.wang" />  

    <!-- 定义视图解析器 -->
    <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" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
         <!--设置文件上传编码-->
         <property name="defaultEncoding" value="UTF-8"/>

     </bean>
</beans>  

2.fileload.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传</title>
<script >
   function check(){
       //通过标签的id属性获取属性值
       var name=document.getElementById("name").value;
       var file=document.getElementById("file").value;
       if(name==""){
            alert("上传人未填写");
            return false;
        }
        if(file.length==0||file==""){
            alert("请选择上传文件");
            return false;
        }
        return true;
   }
</script>
</head>
<body>
   <form action="${pageContext.request.contextPath }/fileUpload"
    method="post" enctype="multipart/form-data" onsubmit="return check()">
    上传人:<input id="name" type="text" name="name" /><br/><br/>
    请选择文件:<input id="file" type="file" name="uploadfile" 
             multiple="multiple" /><br/><br/>
             <input type="submit" value="上传" />
    </form>
</body>
</html>

3.FileIploadController.java

package com.wang;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
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;
@Controller
public class FileUploadController {

    @RequestMapping("/fileUpload")
    /*必须使用注释 @RequestParam("uploadfile")List<MultipartFile> uploadfile
     *否则报Failed to instantiate [java.util.List]: Specified class is an interface错误 
     * */
    public String handleFormUpload(String name, @RequestParam("uploadfile")List<MultipartFile> uploadfile, HttpServletRequest request) {

        // 如果上传文件存在
        if (!uploadfile.isEmpty() && uploadfile.size() > 0) {
            // 遍历文件
            for (MultipartFile file : uploadfile) {

                // 获取上传文件的名称
                String originalFilename = file.getOriginalFilename();
                System.out.println("文件名"+originalFilename);

                // 设置上传文件保存的地址目录
                String dirpath = request.getServletContext().getRealPath("/images");

                File filepath = new File(dirpath);
                // 如果保存文件的目录不存在,创建upload文件夹
                if (!filepath.exists()) {
                    filepath.mkdirs();
                }
                // 使用UUID重新命名上传文件的名称
                String newFilename = name + "_" + UUID.randomUUID() + "_" + originalFilename;
                System.out.println(newFilename);
                try {
                    // 使用MultipartFile的方法将文件上传到指定位置
                    file.transferTo(new File(dirpath +File.separator+ newFilename));
                    System.out.println("目标路径"+dirpath +File.separator+ newFilename);

                    //定义列表保存图片保存的路径
                    List<String> filenames=new ArrayList<String>();
                    filenames.add(newFilename);

                    request.setAttribute("filenames", filenames);
                } catch (Exception e) {

                    e.printStackTrace();
                    return "error";

                }
            }
        }
        return "sucess";
    }
}

4.sucess.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传页面</title>
</head>
<body>
   <h1>文件上传页面</h1>
   <form >
       <table border="1">
          <tr>
             <th>图片展示</th>
         </tr>
          <c:forEach items="${filenames}" var="newfilename">

              <!--路径为以下形式,浏览器可以打开图片-->
             <td><img alt="" src="/FileDownload/images/${newfilename}" width="140" height="170"/> </td>  

          </c:forEach>
       </table>
   </form>
</body>
</html>

5.解决tomcat中图片上传丢失问题:参考博客文章

注:别再开发工具里面重启tomcat,在开发工具里面重启的话,会重新部署,而此时开发工具中是没有那些上传的文件的,自然重新部署会,那些原本上传的文件就不见了,上传文件路径最好设置webapps之外,可以在webapps并行的目录下,建一个upload文件,专门存储应用上传的文件。

    File filepath = new File("F:\\Tomcat7\\apache-tomcat-7.0.79\\images");
                // 如果保存文件的目录不存在,创建upload文件夹
                if (!filepath.exists()) {
                    filepath.mkdirs();
                }

结果演示:

01.默认浏览器打开为:

这里写图片描述
这里写图片描述

02.其他浏览器打开为:

这里写图片描述

(三)实现文件下载

项目结构:
这里写图片描述

01.下载页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传成功</title>
</head>
<body>
   <h1>文件上传成功</h1>
   <form >
       <table border="1">
          <tr>
             <th>图片展示</th>
             <th>操作</th>
          </tr>
          <c:forEach items="${filenames}" var="newfilename">

              <!--路径为以下形式,浏览器可以打开图片-->
             <td><img alt="" src="/FileDownload/images/${newfilename}" width="140" height="170"/> </td>  
              <!--下载图片-->
             <td><a href="${pageContext.request.contextPath}/download?filename=${newfilename}">下载</a></td>
          </c:forEach>
       </table>
   </form>
</body>
</html>

02.FileDownloadController .java

package com.wang;
import java.io.File;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.FileUtils;
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;

@Controller
public class FileDownloadController {

    @RequestMapping("/download")
    public ResponseEntity<byte[]> fileDownload(String filename,
            HttpServletRequest request ) throws IOException{

        //指定下载文件所在的位置
        String path = request.getServletContext().getRealPath("/images");

        //创建文件对象
        File file = new File(path+File.separator+filename);

        //设置响应头
        HttpHeaders headers=new HttpHeaders();

        //通知浏览器下载打开的方式
        headers.setContentDispositionFormData("attachment", filename);

        //以流的方式下载文件数据
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

        //responseEntity封装返回下载的数据
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.OK);


    }
}

结果演示:
这里写图片描述

(四)解决中文名称文件下载

注:一般也不会使用汉字作为资源文件名,没多大意思还给自己带来麻烦!

1.download.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8"%>
<%@page import="java.net.URLEncoder"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
     "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>下载页面</title>
</head>
<body>
    <%-- <a href="${pageContext.request.contextPath }/download?filename=1.jpg">
        文件下载 
    </a> --%>

    <a href="${pageContext.request.contextPath }/download?filename=<%=
                                   URLEncoder.encode("手机.jpg", "UTF-8")%>">
        中文名称文件下载 
    </a>
</body>
</html>

2.FileDownloadController.java

package com.wang;
import java.io.File;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.FileUtils;
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;

@Controller
public class FileDownloadController {


    @RequestMapping("/download")
    public ResponseEntity<byte[]> fileDownload(HttpServletRequest request,
                                               String filename) throws Exception{
        // 指定要下载的文件所在路径
        String path = request.getServletContext().getRealPath("/images");
        // 创建该文件对象
        File file = new File(path+File.separator+filename);
        // 对文件名编码,防止中文文件乱码
        filename = this.getFilename(request, filename);
        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        // 通知浏览器以下载的方式打开文件
        headers.setContentDispositionFormData("attachment", filename);
        // 定义以流的形式下载返回文件数据
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        // 使用Sring MVC框架的ResponseEntity对象封装返回下载数据
       return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
                                               headers,HttpStatus.OK);
    }
    /**
     * 根据浏览器的不同进行编码设置,返回编码后的文件名
     */
    public String getFilename(HttpServletRequest request,
                                                String filename) throws Exception { 
        // IE不同版本User-Agent中出现的关键词
        String[] IEBrowserKeyWords = {"MSIE", "Trident", "Edge"};  
        // 获取请求头代理信息
        String userAgent = request.getHeader("User-Agent");  
        for (String keyWord : IEBrowserKeyWords) { 
             if (userAgent.contains(keyWord)) { 
                  //IE内核浏览器,统一为UTF-8编码显示
                  return URLEncoder.encode(filename, "UTF-8");
             }
        }  
        //火狐等其它浏览器统一为ISO-8859-1编码显示
        return new String(filename.getBytes("UTF-8"), "ISO-8859-1");  
    }  
}

猜你喜欢

转载自blog.csdn.net/weixin_36279318/article/details/79921063
今日推荐