GridFS是MongoDB提供的一种存储大文件的规范,文件在存储的过程中会分成一小块一小块(chunks),文件的信息会保存在另外一个集合中。
通过MD5校验过滤重复上传文件
在换乐网中,所有用户上传的文件都会保存在GridFS中:
通过MD5校验,不上传重复的文件,各种云盘上传文件时的秒传也是类似的功能。这样做的好处就是:服务器中的文件减少了,存储空间占用降低了,用户上传的速度加快了。
关键代码如下:
生成上传文件的MD5码:
Md5PasswordEncoder md5PasswordEncoder=new Md5PasswordEncoder();
String md5String="";
try {
MessageDigest md5Encoder = MessageDigest.getInstance("MD5");
byte[] digest = md5Encoder.digest(file.getBytes());
md5String =new BigInteger(1, digest).toString(16);
System.out.println(md5String);
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
文件上传代码,上传之前会检验MD5码
/**保存文件到GirdFS,通过openUploadStream方式
* @param bucket 容器名称
* @param file 文件实体
* @return 返回FileEntity
*/
public FileEntity save(FileEntity file){
//检查是否之前已有人上传过该文件
FileEntity filter = new FileEntity();
filter.setMd5(file.getMd5());
FileEntity result =this.find(filter);
if(result!=null){
file.setId(result.getId());
return file;
}
//上传该文件
gfsbk = GridFSBuckets.create(db, DEFAULT_BUCKET);
GridFSUploadStream uploadStream = gfsbk.openUploadStream(file.getFileName());
uploadStream.write(file.getContent());
ObjectId id = uploadStream.getFileId();
uploadStream.flush();
uploadStream.close();
file.setId(id);
return file;
}
从GridFS中获取图片显示在jsp页面中
因为MD5码可以标识一个文件,所以网站直接使用MD5码作为参数获取图片,先看下图片控制器:
@Controller
@RequestMapping("/files")
public class FileController {
//TODO : 考虑安全问题,因为只要一个md5码就可以得到文件,是否会有漏洞?
@Autowired
private GirdFSHelper girdFSHelper;
@RequestMapping(method=RequestMethod.GET,path="/image/{key}")
public void changeInfo(HttpServletResponse response,@PathVariable String key){
FileEntity filter = new FileEntity();
filter.setMd5(key);
FileEntity file = girdFSHelper.download(filter);
if(file==null){
//TODO 显示一张默认图片
}else{
response.setContentType("image/*");
try {
response.getOutputStream().write(file.getContent());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
页面中<img>
的src可以这样写:
<img alt="" src="/files/image/9a3e601a54612f89ce6e97cd365a9c65">
如果直接打开这个链接,会下载一个文件,所以这个Controller直接再写一个方法就可以实现其它文件的下载。