SpringMVC中的文件上传和中英文名称文件下载

一、文件上传

前端:

<%@ page language="java" contentType="text/html;charset=UTF-8"
    pageEncoding="UTF-8"%>
<! 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>
<script>
//判断是否填写上传人并已选择文件
function check(){
	var name = document.getElementById("name").value;
	var file = document.getElementById("file").value;
	if(name==""){
		alert("请填写上传人")
		return false;
	}
	if(file==""||file.length==0){
		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/>
	          请选择文件:<input id="file" type="file" name="uploadfile" multiple="multiple" /><br/>
	    <input type="submit" value="上传">
	</form>
        
</body>
</html>

后端:

    /*
	 * 执行文件上传
	 */
	@RequestMapping("/fileUpload")
	public String fileUpload(@RequestParam("name") String name,
			@RequestParam("uploadfile") List<MultipartFile> uploadfile,
			HttpServletRequest request) {
		//判断文件是否存在
		if(!uploadfile.isEmpty()&&uploadfile.size()>0) {
			//循环输出上传的文件
			for (MultipartFile file : uploadfile) {
				//获取文件原始名称
				String originalFilename = file.getOriginalFilename();
				//设置上传文件的保存目录
				String dirPath = request.getServletContext().getRealPath("/upload/");
				File filePath = new File(dirPath);
				//如果保存文件的地址不存在,就先创建目录
				if(!filePath.exists()) {
					filePath.mkdirs();
				}
				//使用UUID重新命名上传的文件
				String newFilename = name+"_"+UUID.randomUUID() + "_"+originalFilename;
				try {
					//使用MultipartFile接口的方法完成文件上传到指定位置
					file.transferTo(new File(dirPath+newFilename));
				} catch (Exception e) {
					e.printStackTrace();
					return "error";
				}
				
			}
			//跳转成功页面
			return "success";
		}else {
			return "error";
		}
	}

二、中英文名称文件下载

如果是简单的英文文件下载不难,但是中文文件下载会出现乱码问题,所以我们利用Servlet API中提供的URLEncoder类中的encoder(String s,String enc)方法将中文转换为UTF-8编码。

注意前端在头部要添加:

<%@page import="java.net.URLEncoder"%>

前端:

<%@ 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>
   <div>
   	<a href="${pageContext.request.contextPath }/fileDownload?filename=1.jpg">
	  文件下载
	</a>
   </div>
	
	<div>
	  <a href="${pageContext.request.contextPath }/fileDownload?filename=<%=URLEncoder.encode("图片.png", "UTF-8") %>">
	    中文文件下载
	  </a>
	</div>
</body>
</html>

后端:

    /*
	 * 执行文件下载
	 */
	@RequestMapping("/fileDownload" )
	public ResponseEntity<byte[]> fileDownload (HttpServletRequest request,String filename) throws Exception {
		//检查文件名是否为空
		if(filename ==null||filename.trim().isEmpty()) {
			throw new IllegalArgumentException("文件名不能为空");
		}
		//指定要下载的文件所在路径
		String path = request.getServletContext().getRealPath("/upload/");
		if(path ==null) {
			//处理path为空的情况
			throw new IOException("无法获取文件路径");
		}
		//创建该文件对象
		File file = new File (path+File.separator+filename) ;
		if(!file.exists()||!file.isFile()) {
			//处理文件不存在的情况
			throw new FileNotFoundException("请求的文件不存在");
		}
		//对文件名编码,防止中文文件乱码
		filename = this.getFilename(request, filename);
		//设置响应头
		org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
		//通知浏览器以下载的方式打开文件
		headers.setContentDispositionFormData ("attachment",filename);
		//定义以流的形式下载返回文件数据
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM) ;
		//使用files工具类将文件转换为字节数组
		byte[] bytes = Files.readAllBytes(file.toPath());
		//返回实体对象
		return new ResponseEntity<> (bytes,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");
	}

一开始,不知道哪里出错,所以抛出异常处理,最终发现问题,由于我在编写前端代码时:多写空格了,如下图所示:

所以在浏览器中报错如下:

最后修改代码,完美解决。

相关推荐
XiaoLeisj25 分钟前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck26 分钟前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei26 分钟前
java的类加载机制的学习
java·学习
Yaml42 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~2 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616882 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7893 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java3 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
睡觉谁叫~~~3 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
程序媛小果4 小时前
基于java+SpringBoot+Vue的旅游管理系统设计与实现
java·vue.js·spring boot