1. 准备工作
1.1. 添加依赖
需要
commons-fileupload-xxx.jar
commons-io-xxx.jar
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
1.2. 修改spring-mvc 配置文件
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 默认编码 -->
<property name="defaultEncoding" value="utf-8" />
<!-- 文件大小最大值 -->
<property name="maxUploadSize" value="10485760000" />
<!-- 内存中的最大值 -->
<property name="maxInMemorySize" value="40960" />
</bean>
2. 文件上传
v 请求方式:post
v 请求enctype: multipart/form-data
<form id="upForm"method="POST" enctype="multipart/form-data">
<ul>
<li>标题:<input type="text" name="title"/>
<li>文件:<input type="file" name="upfile"/>
<li><input type="button" id="uploadBtnId"value="保存"/>
</ul>
</form>
@RequestMapping("/save")·
@ResponseBody
publicJsonResult<Object> saveObject(@RequestParam("title")Stringtitle,
@RequestParam("upfile")MultipartFileupfile,HttpSession session){
//获得服务器上的upload路径
String realPath =session.getServletContext().getRealPath("/");
attachementService.saveObject(title,realPath,upfile);
returnnewJsonResult<Object>();
}
2.3. 文件上传(Service)
publicvoidsaveObject(String title,String realPath,MultipartFile upfile) {
// 获得服务器上的upload路径
String savePath = "/upload/" +DateFormatUtils.format(new Date(), "yyyy/MM/dd");
// 构建上传文件的存储目录结构
String fileDir = realPath + savePath;
// 获得原始文件名
String fileOriginalName =upfile.getOriginalFilename();
// 获得原始文件扩展名
String fileExtName = "." +FilenameUtils.getExtension(fileOriginalName);
// UUID 产生随机字符串的类
//newFileName 是一个随机字符串
String newFileName =UUID.randomUUID().toString() + fileExtName;
// 构建新的文件对象
File newFile = newFile(fileDir, newFileName);
System.out.println("newFile.getPath()=" +newFile.getPath());
File parent = newFile.getParentFile();
if(!parent.exists())
parent.mkdirs();
// 获得文件对应的字节数组
bytebyteArray[];
try {
byteArray = upfile.getBytes();
} catch(IOException e1) {
e1.printStackTrace();
thrownewRuntimeException("文件上传失败", e1);
}
// 构建文件的MD5摘要
String md5Str =MD5.MD5Encode(byteArray);
System.err.println("md5Str=" + md5Str);
int count =attachementMapper.findObjectByDigest(md5Str);
if (count !=0)
thrownewRuntimeException("file already exists");
//上传文件
Path path =Paths.get(newFile.getAbsolutePath());
try{
Files.write(path, byteArray);
}catch(IOExceptione){
e.printStackTrace();
thrownewRuntimeException("file upload faile");
}
// 将文件信息写到数据库
Attachement a = newAttachement();
a.setTitle(title);
a.setFileName(upfile.getOriginalFilename());
a.setContentType(upfile.getContentType());
a.setFileDigest(md5Str);
String filePath =FilenameUtils.concat(savePath, newFileName);
System.err.println(filePath);
a.setFilePath(filePath);
int result =attachementMapper.insertObject(a);
if (result ==-1)
thrownewRuntimeException("save error");
}
3. 文件下载
方法1:
@RequestMapping("/downById.do")
@ResponseBody
publicJsonResult<String> downById(String id,HttpServletRequestrequest,HttpServletResponse response){
Map<String, Object> map =attachementService.findObjectById(id);
String filePath = (String) map.get("filePath");
String fileName = (String) map.get("fileName");
String basePath =request.getServletContext().getRealPath("/");
File file = newFile(basePath,filePath);
if(!file.exists())thrownewRuntimeException("file not found");
try{
fileName = newString(fileName.getBytes("UTF-8"),"ISO8859-1");
}catch(UnsupportedEncodingExceptione){
e.printStackTrace();
thrownewRuntimeException("编码转换异常");
}
response.setContentType("appliction/octet-stream");
response.setHeader("Content-disposition","attachment;filename="+fileName);
Path path=Paths.get(file.getPath());
try{
Files.copy(path,response.getOutputStream());
}catch(Exceptione){
thrownewRuntimeException("文件下载失败");
}
returnnew JsonResult<String>();
}
方法2:
@RequestMapping("/doDownload")
@ResponseBody
publicbyte[]doDownload(Integer id,
HttpServletResponse response)throwsIOException{
File file=
attachementService.findObjectById(id);
//设置响应消息头(下载时的固定写法)
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition","attachment;filename="+file.getName());
//根据文件真实路径构建一个Path对象
Path path=Paths.get(file.getPath());
//将文件的字节返回(spring mvc 会自动将这字节写入到文件)
return Files.readAllBytes(path);
//returnfile;
}
@Override
public FilefindObjectById(Integer id) {
if(id==null)
thrownewRuntimeException("id can not be null");
//1.根据id查找记录
Attachement a=
attachementDao.findObjectById(id);
if(a==null)
thrownewRuntimeException("数据库中没有对应的记录信息");
//2.获得文件的真实路径,构建文件对象关联真实路径
File file=new File(a.getFilePath());
//3.检测文件是否存在,存在则下载
if(!file.exists())
thrownewRuntimeException("文件已经不存在");
returnfile;
}
4. 文件工具类
4.1. MD5 加密
publicclass MD5{
privatefinalstatic String[]hexDigits = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
/**
* 转换字节数组为16进制字串
* @param b 字节数组
* @return 16进制字串
*/
publicstatic StringbyteArrayToHexString(byte[] b) {
StringBuffer resultSb = new StringBuffer();
for (inti = 0; i < b.length; i++) {
resultSb.append(byteToHexString(b[i]));
}
returnresultSb.toString();
}
privatestatic StringbyteToHexString(byteb) {
intn = b;
if (n < 0)
n = 256 + n;
intd1 = n / 16;
intd2 = n % 16;
returnhexDigits[d1] + hexDigits[d2];
}
publicstatic StringMD5Encode(String origin) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
} catch (Exceptionex) {}
returnresultString;
}
publicstatic StringMD5Encode(byte[] array) {
String resultString = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(array,0,array.length);
resultString = byteArrayToHexString(md.digest());
} catch (Exceptionex) {
ex.printStackTrace();
}
returnresultString;
}
}