SpringMVC复习:文件上传和下载

1.介绍

由于前面对于Spring中的DispatcherServlet源码解析后发现需要通过配置的方式才能使用文件上传,所以让我想起了文件的上传和下载!

2.pom依赖

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>5.1.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
	<groupId>commons-io</groupId>
	<artifactId>commons-io</artifactId>
	<version>2.4</version>
</dependency><!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
	<groupId>commons-fileupload</groupId>
	<artifactId>commons-fileupload</artifactId>
	<version>1.3.3</version>
</dependency>

3.配置文件上传的解析器

	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 设置默认的最大的上传文件大小为1024*1024*2=2M -->
		<property name="maxUploadSize" value="2097152"/>
		<property name="defaultEncoding" value="UTF-8"/>
	</bean>

4.创建html页面

index页面

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Insert title here</title>
</head>
<body>
	<h2>欢迎访问当前的index页面</h2>
	<form action="hi" method="post">
		使用自定义的日期格式转换器:<input type="text" name="now"/>
		<input type="submit" value="提交"/>
	</form>
	<a href="upload.html">前往上传文件的页面</a>
	<a href="download.html">前往下载文件的页面</a>
</body>
</html>

文件上传的页面

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Insert title here</title>
</head>
<body>
	<h2>欢迎访问当前的upload页面</h2>
	<form action="upload" method="post" enctype="multipart/form-data">
		选择上传文件:<input type="file" name="file"/>
		<input type="submit" value="提交"/>
	</form>
</body>
</html>

文件下载的页面

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Insert title here</title>
</head>
<body>
	<h2>欢迎访问当前的download页面</h2>
	<button onclick="location.href='download?downloadFileName=使用js后生成的二维码.png'">下载二维码文件</button>
</body>
</html>

5.这里使用的图片

在这里插入图片描述

6.创建工具类

web工具


import java.io.File;
import java.net.MalformedURLException;
import javax.servlet.http.HttpServletRequest;

public abstract class WebUtils {
	public static final String DEFAULT_UPLOAD_DIR = "upload";
	public static final String DEFAULT_DOWNLOAD_DIR = "upload";

	public static File getWebFile(final String uploadDir, final String originalFilename,HttpServletRequest request) throws MalformedURLException {
		String webDirPath = getWebDirPath(uploadDir,request);
		final File destFile = new File(webDirPath + File.separator + originalFilename);
		return destFile;
	}

	// 例如:/upload
	public static String getWebDirPath(final String uploadDir,HttpServletRequest request) throws MalformedURLException {
		String upload = uploadDir;
		if (upload == null || "".equals(upload.trim())) {
			upload = DEFAULT_UPLOAD_DIR;
		}
		
		final String uploadUrl = request.getServletContext().getRealPath(File.separator+upload);
		return uploadUrl;
	}
}

文件上传的工具

import java.io.File;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.multipart.MultipartFile;
import com.hy.spring.util.web.WebUtils;

public abstract class FileUploadUtils {
	public static void saveUploadFile(final MultipartFile uploadFile, final String savePath, HttpServletRequest request)
			throws IOException {
		if (uploadFile == null || uploadFile.isEmpty()) {
			throw new IllegalArgumentException("当前操作的文件为空,请检查文件是否上传成功!");
		}
		final String uploadDirPath = savePath;
		final String originalFilename = uploadFile.getOriginalFilename();
		final File destFile = WebUtils.getWebFile(uploadDirPath, originalFilename, request);
		uploadFile.transferTo(destFile);
	}

}

文件下载的工具类

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Date;
import javax.activation.MimetypesFileTypeMap;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import com.hy.spring.util.io.IOUtils;

public abstract class FileDownloadUtils {
	public static void downloadFile(HttpServletResponse response, File file) throws IOException {
		if (file == null || !file.exists() || !file.isFile()) {
			throw new IllegalArgumentException("传入的文件有问题请检查当前的文件是否存在!");
		}
		// 设置默认下载的响应头
		setDefaultHeader(response,file);
		ServletOutputStream outputStream = response.getOutputStream();
		InputStream in = IOUtils.getInputStreaByFile(file);
		IOUtils.writeFile(in, outputStream);
	}

	//设置默认的响应流
	private static void setDefaultHeader(HttpServletResponse response,File file) throws IOException {
		response.setContentType(new MimetypesFileTypeMap().getContentType(file));// 设置response内容的类型
		String fileName = URLEncoder.encode(file.getName(),"utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
		response.addDateHeader("downloadTime", new Date().getTime());

	}
}

io工具


public abstract class IOUtils {
	// 写文件
	public static void writeFile(InputStream in, OutputStream os) throws IOException {
		byte[] buffer = new byte[1024];
		int start = 0;
		try {
			while ((start = in.read(buffer)) != -1) {
				os.write(buffer, 0, start);
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} finally {
			closeStream(in);
			closeStream(os);
		}
	}
	

	// 关闭输入流
	public static void closeStream(InputStream in) {
		if (in != null)
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
	}
	//关闭输出流
	public static void closeStream(OutputStream os) {
		if (os != null)
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
	}
	//通过文件获取输入流
	public static InputStream getInputStreaByFile(File file) throws FileNotFoundException {
		return new FileInputStream(file);
	}
}

这里需要注意的是:

1.文件上传中需要通过servletContext获取当前web应用的文件路径

2.文件下载的时候需要指定当前的http的content-type为上次在Nginx中的内容(二进制文件流),还需要指定当前的Content-disposition, attachment;filename=XXX

3.使用中文作为下载名的时候需要使用URLEncoder进行对中文的加码,不然会出现中文无法解析的问题!

7.创建对应的controller

文件上传controller

/**
 * @description 文件上传的controller
 * @author hy
 * @date 2019-10-30
 */
@RestController
public class UploadController {
	@PostMapping("/upload")
	public String uploadFile(@RequestParam("file") MultipartFile multipartFile, HttpServletRequest request)
			throws IOException {
		FileUploadUtils.saveUploadFile(multipartFile, "/upload", request);
		return "{\"result\":\"success\",\"option\":\"upload\"}";
	}

	@ExceptionHandler
	public String catchException(Exception e) {
		return "{\"result\":\"fail\",\"option\":\"upload\"}";
	}

}

文件下载controller

@RestController
public class DownloadController {
	@GetMapping("/download")
	public String downloadFile(String downloadFileName, HttpServletResponse response, HttpServletRequest request)
			throws IOException {
		File downloadFile = WebUtils.getWebFile(WebUtils.DEFAULT_DOWNLOAD_DIR, downloadFileName, request);
		FileDownloadUtils.downloadFile(response, downloadFile);
		return "{\"result\":\"success\",\"option\":\"download\"}";
	}

	@ExceptionHandler
	public String catchException(Exception e) {
		return "{\"result\":\"fail\",\"option\":\"download\"}";
	}

}

8.测试结果

上传文件的结果就不显示了!

在这里插入图片描述

9.总结

1.通过源码解析后,发现文件上传解析器必须配置在xml中否者就会从当前的bean工厂中找一个id为multipartResolver的文件上传解析器

2.再次使用发现了在文件上传中需要在controller中指定@RequestParam指定上传文件的名称

3.下载的时候需要注意乱码问题!

以上纯属个人见解,如有问题请联系本人!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值