文件上传和下载,在上传的操作之后,跳转到下载页面

源码获取github

1.项目结构

2.上传操作

单文件的上传

  • form表单传递数据
  • 请求必须为POST请求
  • 使用二进制流的方式传递数据 enctype=”multipart/form-data”
  • 文件域 <input type=”file” name=”myfile”/>
  • 上传的工具有两种:
    • Servlet3.0
    • Commons-FileUpload
    • commons-fileupload.jar
    • commons-io.jar

第一步:配置解析器

springmvc.xml加入

<!--5.使用上传的解析器,如果发现是上传操作,会自动使用该解析器帮我们完成相应的操作-->
<!--该ID为固定值-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
   <!--设置上传文件编码-->
   <!--简写方式 标签p c注入 p:defaultEncoding = "UTF-8"-->
   <property name="defaultEncoding" value="UTF-8"/>
   <!--设置文件上传最大值024*200即200K-->
   <property name="maxUploadSize" value="20971520"/>
   <!--缓存,读取文件到内存中最大的字节数,可以不设置-->
   <property name="maxInMemorySize" value="2048"/>
   <!--延时提高上传效率,一个类似懒加载的属性-->
   <property name="resolveLazily" value="true"/>
</bean>

如果是图片资源,还要配置静态资源排除,见之前的笔记

第二步:前端页面表单和前台验证

file.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>Title</title>
</head>
<body>
<h2>单文件上传</h2>
<form action="upload01" method="post" enctype="multipart/form-data" id="uploadForm">
   标题:<input type="text" name="title">
   文件:<input type="file" name="myfile" id="myfile"><br>
   <button>文件上传</button>
</form>
<script type="text/javascript" src="resource/jquery.js"></script>
<script type="text/javascript"> $(function () { //元素选择器 $("button").click(function () { //1.获取上传文件的对象,是数组,获取的第一个 var myfile = $("#myfile").prop("files")[0]; //2.判断文件是否有 if (myfile) { //3.获取文件名称 var fileName = myfile.name; //4.获取文件的后缀名称 var ext = fileName.substring(fileName.lastIndexOf(".") + 1); //5.设置允许上传的文件后缀名称 var allowFileTypes = ["jpg", "png", "gif", "jpeg", "dmp", "rar"]; //6.设置一个标识,用来做判断 var flag = false; //循环判断上传格式是否正确 for (var i = 0; i < allowFileTypes.length; i++) { if (ext == allowFileTypes[i]) { flag = true; break; } } if (!flag) { alert("您上传的文件格式不正确,允许的格式为:" + allowFileTypes.join(" | ")); return false; } //7.判断文件的大小 if (myfile.size > 20 * 1024 * 1024) { alert("您上传的文件过大,请重新选择") } return false; //8.表单提交 ${"#uploadForm"}.submit(); } else { alert("请选择您要上传的文件"); return false; } }) }) </script>
</body>
</html>

第三步:后台处理

UploadDemoController.java

package com.hs.web;

import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Random;

/** * 文件上传操作 */
@Controller
public class UploadDemoController {

   /** * 单文件上传_标准写法 * * @param title * @param myfile * @param request * @return */
   @PostMapping("/upload01")
   public ModelAndView test01(String title, MultipartFile myfile, HttpServletRequest request) throws IOException {
      ModelAndView mav = new ModelAndView();
// System.out.println(title);
      //1.获取上传文件的名称
      String fileName = myfile.getOriginalFilename();
      mav.addObject("fileName", fileName);
      //2.判断文件名称是否有值,isEmpty是这个字符串的length=0为true
      if (!fileName.isEmpty()) {
         //3.获取服务器的绝对路径
         String path = request.getServletContext().getRealPath("/upload");
         //4.建立联系
         File folder = new File(path);
         //5.判断该文件是否存在,不存在则创建文件夹
         if (!folder.exists()) {
            folder.mkdirs();    //创建文件夹
         }
         //6,获取上传文件的后缀名称
         String ext = FilenameUtils.getExtension(fileName);
         //7.创建新的文件名称
         //String newFileName = UUID.randomUUID().toString() + "." + ext;
         //或者用时间戳创建名称
         String newFileName = new Date().getTime() + "_" + new Random().nextInt(100000) + "." + ext;
         mav.addObject("newFileName", newFileName);
// System.out.println(newFileName);
         //8.文件上传,File.separator为斜线
         myfile.transferTo(new File(path + File.separator + newFileName));
      }
      mav.addObject("hs", "和尚");
      mav.setViewName("jsp/result");
      /*System.out.println("测试是否可以获取正常的数据:"+title); System.out.println("====="); System.out.println("文件的MIME类型 :"+myfile.getContentType()); System.out.println("文件NAME属性对应的值 :"+myfile.getName()); System.out.println("上传文件的名称 :"+myfile.getOriginalFilename()); System.out.println("上传文件的大小 :"+myfile.getSize());*/
      return mav;
   }
}

3.下载操作

方式一:直接超链接方式显示

result.jsp

<h2>直接超链接方式显示</h2>
<a href="upload/${newFileName }">${fileName }</a>

方式二:HTML5 中的download属性

<h2>HTML5 中的download属性</h2>
<a href="upload/${newFileName }" download="${fileName }">${fileName }</a>

方式三:使用流的方法–到控制层处理

<h2>使用流的方法--到控制层处理,发送请求到控制器,download</h2>
<a href="download?newFileName=${newFileName}&fileName=${fileName}">${fileName }下载</a>

在springmvc.xml声明处理byte数组,在解决@ResponseBody在IE浏览器的BUG问题上面

<!--解决下载的时候转换问题,声明处理byte数组-->
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>

DownloadDemoController.java处理流

package com.hs.web;

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.GetMapping;

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

/** * 文件下载操作 */
@Controller
public class DownloadDemoController {
   /** * 文件下载,使用流的方法 * * @param newFileName * @param fileName * @param request * @return * @throws IOException */
   @GetMapping("/download")
   public ResponseEntity<byte[]> test02(String newFileName, String fileName, HttpServletRequest request) throws IOException {
      //获取服务端的绝对路径
      String path = request.getServletContext().getRealPath("/upload/");

      HttpHeaders headers = new HttpHeaders();
      //设置相应的内容为流
      headers.setContentType(MediaType.TEXT_EVENT_STREAM);
      //设置下载的名称--和中文乱码的问题
      headers.setContentDispositionFormData("attachment",
            new String(fileName.getBytes("UTF-8"), "ISO8859-1")
            );
      //找到文件
      File file = new File(path + File.separator + newFileName);
      return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),/*将文件转换为byte数组*/
            headers,
            HttpStatus.CREATED);

   }
}