springmvc下载文件示例
- 使用递归获取所有文件名
- 下载文件方法
- 前台页面显示
- js请求
1.递归代码块
/**
* 递归遍历指定目录下的所有文件
*
* @param file
* @param map
*/
public void listfile(File file, Map<String, String> map) {
// 如果file代表的不是一个文件,而是一个目录
if (!file.isFile()) {
// 列出该目录下的所有文件和目录
File files[] = file.listFiles();
// 遍历files[]数组
for (File f : files) {
listfile(f, map);
}
} else {
/**
* 处理文件名,上传后的文件是以uuid_文件名的形式去重新命名的,去除文件名的uuid_部分
* file.getName().indexOf("_")检索字符串中第一次出现"_"字符的位置,如果文件名类似于:
* 9349249849-88343-8344_阿_凡_达.avi
* 那么file.getName().substring(file.getName().indexOf("_")+1)
* 处理之后就可以得到阿_凡_达.avi部分
*/
String realName = file.getName().substring(file.getName().indexOf("_") + 1);
// file.getName()得到的是文件的原始名称,这个名称是唯一的,因此可以作为key,realName是处理过后的名称,有可能会重复
map.put(file.getName(), realName);
}
}
@RequestMapping(value = "/listFile", method = { RequestMethod.GET,
RequestMethod.POST }, produces = "application/json;charset=UTF-8")
public @ResponseBody Map<String, String> listFile() {
// 获取上下文目录
ServletContext sc = web.getServletContext();
// 文件位置
String uploadFilePath = sc.getRealPath("/images") + "/";
System.out.println("查看文件位置:" + uploadFilePath);
// 存储要下载的文件名
Map<String, String> fileNameMap = new HashMap<String, String>();
// 递归遍历filepath目录下的所有文件和目录,将文件名存储到map集合中
listfile(new File(uploadFilePath), fileNameMap);
return fileNameMap;
}
脚注
web对象请求是WebApplicationContext web = ContextLoader.getCurrentWebApplicationContext();
2.下载文件方法代码块
/**
* 文件下载方法
*
* @param request
* @param response
*/
@RequestMapping(value = "/downFile", produces = "application/json;charset=UTF-8")
public @ResponseBody String downFile(@RequestParam("filename") String filename, HttpServletResponse response) {
System.out.println("进入下载方法" + filename);
// 获取上传文件的目录
ServletContext sc = web.getServletContext();
try {
//filename = new String(filename.getBytes("ISO8859-1"), "UTF-8");
String fileSaveRootPath = sc.getRealPath("/images");
System.err.println(fileSaveRootPath + "\\" + filename);
// 得到要下载的文件
File file = new File(fileSaveRootPath + "\\" + filename);
// 如果文件不存在
if (!file.exists()) {
System.out.println("资源已删除");
return "您要下载的资源已被删除!!";
}
// 处理文件名
String realname = filename.substring(filename.indexOf("_") + 1);
System.out.println("查看处理文件名:" + realname);
// 设置响应头部,控制浏览器下载文件
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
// 读取下载的文件,保存到文件输入流中
FileInputStream in = new FileInputStream(fileSaveRootPath + "\\" + filename);
// 创建文件输出流
OutputStream out = response.getOutputStream();
// 创建缓冲区
byte buffer[] = new byte[1024];
int len = 0;
// 循环将输入流中的内容读取到缓冲区当中
while ((len = in.read(buffer)) > 0) {
// 输入缓冲 去的内容到浏览器,实现文件下载
out.write(buffer, 0, len);
}
in.close();
out.close();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.err.println("查看是否进入");
return "下载成功";
}
脚注
编码容易出现乱码问题,需统一编码格式
3.前台页面显示代码块
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>下载文件测试•</title>
</head>
<#assign context=request.getContextPath()>
<script type="text/javascript"
src="${context}/statics/baseJs/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
var context = "${context}";
</script>
<script type="text/javascript" src="${context}/statics/js/download.js"></script>
<style>
.div {
width: 30%
}
.div p {
width: 50%;
margin: 0px;
float: left;
}
</style>
<body>
<div>测试下载</div>
<div class="div" id="test"></div>
</body>
</html>
脚注
因为使用freemarker,基本项目都是html,在用freemarker标签获取上下文配置时,需在配置文件中添加下面代码
<!-- 获取request -->
<property name="requestContextAttribute" value="request" />
4.js请求代码
$(function() {
$.ajax({
url : context + "/file/listFile",
type : "post",
success : function(data) {
var div = "";
$.each(data, function(i, n) {
div += "<div><p>" + n + "</p><a href='" + context
+ "/file/downFile?filename=" + n + "'>下载</a></div>";
})
$("#test").append(div);
}
})
})
脚注
习惯使用jQuery的ajax请求,发过来的json可以把url请求也封装好,a标签上出现乱码一般情况是编码不统一的问题
第一次发博客,写的应该不详细,请多谅解