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");
	}

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

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

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

相关推荐
用户58271173081310 分钟前
@SchedulerLock注解配置不当导致数据重复问题解决方案
java
诺亚凹凸曼11 分钟前
23种设计模式-结构型模式-桥接器
android·java·设计模式
工业互联网专业24 分钟前
基于springboot+vue的校园数字化图书馆系统
java·vue.js·spring boot·毕业设计·源码·课程设计·校园数字图书馆系统
严文文-Chris43 分钟前
【MVC简介-产生原因、演变历史、核心思想、组成部分、使用场景】
mvc
日月星辰Ace1 小时前
SpringBootTest 不能使用构造器注入
java·spring boot
一只小闪闪1 小时前
langchain4j搭建失物招领系统(五)---实现失物登记功能-大模型流式输出
java·人工智能·后端
SimonKing1 小时前
Kafka 4.0.0震撼来袭,彻底摒弃Zookeeper
java·后端·架构
Java技术小馆1 小时前
在分布式系统中如何应对网络分区
java·面试·架构
学也不会1 小时前
d2025331
java·数据结构·算法
MaCa .BaKa1 小时前
27-衣橱管理系统(小程序)
java·vue.js·spring boot·小程序·架构·uni-app·maven