在JAVA的SpringMVC架构下,实现附件上传下载功能

 

首先 前端上传附件时前端需要更改form表单的enctype属性。

form表单的enctype属性:规定了form表单数据在发送到服务器时候的请求体的编码类型。

application/x-www-form-urlencoded:默认编码方式

multipart/form-data:指定传输数据为二进制数据,例如图片、mp3、文件

text/plain:纯文本的传输。空格转换为“+”,但不支持特殊字符编码。

 

application/x-www-form-urlencoded的使用情况

我们平常前端传给后端过程中,常把参数的json对象转化为json对象字符串形式,传递时使用的是默认的编码方式application/x-www-form-urlencoded,在Postman测试工具中也经常用到此方式来验证接口功能。

JAVA:springMVC附件上传下载功能_文件名

 

当要上传附件类型时,前端页面需使用multipart/form-data。用PostMan代替前端页面测试时同样也是选择multipart/form-data类型。

<form action="" method="post" enctype="multipart/form-data">
用户名 <input type="text" name="user">
头像 <input type="file" name="avatar">
<input type="submit">
</form>

以下转入正题,后端服务如何实现。

1.附件上传

UploadFileController 文件

/**
* 添加附件
*/
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public void upload(@RequestParam HashMap<String, String> map,
@RequestParam(value = "file") MultipartFile file) {
String estr = "添加附件 (uploadFile/upload)====:";
try {
System.out.println(estr + "map:" + map.toString() + "file:" + file.getOriginalFilename());
if (file.isEmpty()) {
System.out.println(estr + "file不能为空.");
return ;
}
String fno= FileOperateUtil.uploadFile(file);// 调用上传附件方法,

// 上传成功后将返回的附件编号fno存入数据库用于后续查询
//....

return ;
} catch (Exception e) {
System.out.println(estr + e.getMessage());
return ;
}
}

FileOperateUtil.java:附件上传功能代码

// 上传附件
public static String uploadFile(MultipartFile file) {
String estr = "文件上传 (fileOper/uploadFile)===:";
try {
HashMap<String, Object> attachment = new HashMap<String, Object>();
int flag = 0;// 是否上传的标记
if (null != file && file.getSize() >= 0) {
String uploadDir = "C:\files";// 上传目录
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMM");
String dateStr = dateFormat.format(date);
uploadDir += dateStr;
uploadDir += File.separator;
String fileName = file.getOriginalFilename();
File f = new File(uploadDir);
if (!f.exists()) {
f.mkdirs();
}
// 文件大小、格式等验证
if (file.getSize() > 1024 * 1024 * 60) {
flag = -1;
} else {
//源文件名重命名为物理文件名
String storeName = rename(fileName);
String noZipName = uploadDir + storeName;
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(noZipName));
//数据流操作
FileCopyUtils.copy(file.getInputStream(), outputStream);
if (-1 == flag) {
System.out.println("文件大小超过限制.");
} else if (-2 == flag) {
System.out.println("文件格式不合法.");
}
}
return storeName;//返回物理文件名用于调用方保存到数据库

} catch (Exception e) {
e.printStackTrace();
}
return "";
}


/**
* 将上传的文件进行重命名
*/
public static String rename(String name) {
Long now = Long.parseLong(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
Long random = (long) (Math.random() * now);
String fileName = now + "" + random;

if (name.indexOf(".") != -1) {
fileName += name.substring(name.lastIndexOf("."));
}
return fileName;
}

2.附件下载

UploadFileController 文件

/**
* 下载附件
*/
@RequestMapping(value = "/download", method = RequestMethod.GET)
public void download(HttpServletResponse response, @RequestParam(value = "fu_no") String fu_no) {
String estr = "下载附件(uploadFile/download)====:";
try {
System.out.println(estr + "fu_no:" + fu_no);
if (Comm.IsNullOrEmpty(fu_no)) {
System.out.println("fu_no不能为空.");
return;
}
// 从数据库里面根据附件编号查询附件基本信息
HashMap<String, Object> tmap = new HashMap<String, Object>();
tmap = uploadFileDAO.getOneByFuno(fu_no);
String fu_realname = tmap.getOrDefault("fu_realname", "").toString();
String fu_origname = tmap.getOrDefault("fu_origname", "").toString();
String uploadDir = Comm.xmlReadConfig("sysconfig,upload_filepath");

// 调用下载附件方法,在浏览器请求地址执行成功后,会自动弹出下载提示
FileOperateUtil.download(response, fu_realname, fu_origname, uploadDir);
return;
} catch (Exception e) {
System.out.println(estr + e.getMessage());
return;
}
}

FileOperateUtil.java:附件下载功能代码

/**
* 下载附件
* @param response
* @param realname 物理文件名
* @param origname 源文件名
* @param uploadDir 下载目录名
*/
public static void download(HttpServletResponse response, String realname, String origname, String uploadDir) {
String estr = "文件下载 (fileOper/download)===:";
try {
response.setContentType("text/html;charset=UTF-8");
BufferedInputStream bis = null;
BufferedOutputStream bos = null;

realname = new String(realname.getBytes("ISO-8859-1"), "UTF-8");// 物理文件名
origname = new String(origname.getBytes("ISO-8859-1"), "UTF-8");// 源文件名
String timeStr = realname.substring(0, 6);
String downLoadPath = uploadDir + timeStr + File.separator + realname;
long fileLength = new File(downLoadPath).length();
//建立物理文件的数据流
bis = new BufferedInputStream(new FileInputStream(downLoadPath));

response.reset();
response.setContentType("bin");
response.addHeader("Content-disposition",
"attachment; filename=" + new String(origname.getBytes("utf-8"), "ISO8859-1"));
response.addHeader("Content-Length", String.valueOf(fileLength));

byte[] buff = new byte[2048];
int bytesRead;
//在response里创建输出流
bos = new BufferedOutputStream(response.getOutputStream());
//读取物理文件的数据流到输出流
while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
bos.flush();
bis.close();
bos.close();
return;
} catch (Exception e) {
e.printStackTrace();
return;
}
}