mongodb+GridFS文件的上传下载删除

1、背景
最近项目使用mongDB做文件服务器,用于文件存储。所以稍微研究了下mongDB API写了个简单文件上传下载删除示例
2、具体代码
完整demo下载路径:http://download.csdn.net/detail/szs860806/9846782 代码中有完整注释。这里就不一一赘述了。我这里使用的是fileupload做的上传。这里是使用的jar: mongodb+GridFS文件的上传下载删除
文章图片
代码是用servlet写的,有点长。

package com.yqfz.Servlet; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import com.mongodb.DB; import com.mongodb.MongoClient; import com.mongodb.ServerAddress; import com.mongodb.gridfs.GridFS; import com.mongodb.gridfs.GridFSDBFile; import com.mongodb.gridfs.GridFSInputFile; import com.yqfz.pojo.FileInfo; import com.yqfz.util.BaseResult; import com.yqfz.util.FileUtils; import com.yqfz.util.PropertiesUtils; public class IUploadServlet extends HttpServlet { /** * 注释内容 */ private static final long serialVersionUID = 1L; // 上传配置 private static final int MEMORY_THRESHOLD = 1024 * 1024 * 10; // 3MBprivate static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MBprivate static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MBprivate static final Long DEFAULT_CHUNK_SIZE = 1024 * 1024 * 10L; private static final String NOT_RENAME = "1"; // 不重命名private String showPath = PropertiesUtils.loadProperty("conf.properties").get("file_show_url"); // 文件显示路径private MongoClient mongo = null; private DB db = null; private GridFS gridFS = null; private BaseResult baseResult = null; public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doPost(req, res); }public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { String method = req.getParameter("method"); if (method.equals("upload")) { upload(req, res); } else if (method.equals("delete")) { delete(req, res); } else if (method.equals("downloadFile")) { downloadFile(req, res); } }@SuppressWarnings("unchecked") private void upload(HttpServletRequest req, HttpServletResponse res) { baseResult = new BaseResult(); try { if (checkForm(req, res))// 检测是否为多媒体上传 return; String appDir = req.getParameter("appDir"); // 获取上传应用类型 String type = req.getParameter("type"); // 是否需要重命名0或者不传为需要,1为不需要 System.out.println("打印参数:appDir=" + appDir + ",type=" + type); ServletFileUpload upload = initFileUpload(); // 初始化fileUpload List fileItems = upload.parseRequest(req); if (fileItems != null && fileItems.size() > 0) { initMongo(); // 初始化mongoDB String fileShowPath = getFileShowPath(appDir); // 获取展示地址 List fileList = new ArrayList(); for (FileItem item : fileItems) { if (!item.isFormField() && item.getSize() > 0) { System.out.println("处理上传的文件 begin"); String oldFileName = item.getName(); String newFileName = getNewFileName(type, oldFileName); GridFSInputFile file = saveFile(item, newFileName); // 生成文件信息 FileInfo fileInfo = new FileInfo(file.getId() + "", newFileName, oldFileName, FileUtils.formetFileSize(item.getSize()), fileShowPath + "/" + newFileName); fileList.add(fileInfo); System.out.println("处理上传的文件 end"); } }baseResult.setError("上传成功"); baseResult.setErrorCode("0000"); baseResult.setResult(fileList); } else { baseResult.setError("没有上传文件"); baseResult.setErrorCode("1000"); }if (!NOT_RENAME.equals(type)) { ajaxOut(baseResult.toString(), res); } } catch (Exception e) { System.out.println("使用 fileupload 包时发生异常 ..."); e.printStackTrace(); baseResult.setError("上传失败"); baseResult.setErrorCode("1000"); ajaxOut(baseResult.toString(), res); } }private void downloadFile(HttpServletRequest req, HttpServletResponse res) { baseResult = new BaseResult(); try { String appDir = req.getParameter("appDir"); String filename = req.getParameter("filename"); System.out.println("打印参数:appDir=" + appDir + ",filename=" + filename); initMongo(); getFileShowPath(appDir); GridFSDBFile gridFSDBFile = (GridFSDBFile)gridFS.findOne(filename); if (gridFSDBFile != null) {OutputStream sos = res.getOutputStream(); res.setCharacterEncoding("UTF-8"); res.setHeader("Access-Control-Allow-Origin", "*"); res.setContentType("application/octet-stream"); res.addHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); gridFSDBFile.writeTo(sos); sos.flush(); sos.close(); } } catch (Exception e) { System.out.println("下载文件异常 ..."); e.printStackTrace(); baseResult.setError("下载文件失败"); baseResult.setErrorCode("1000"); ajaxOut(baseResult.toString(), res); } }private void delete(HttpServletRequest req, HttpServletResponse res) { baseResult = new BaseResult(); try { String appDir = req.getParameter("appDir"); String filename = req.getParameter("filename"); System.out.println("打印参数:appDir=" + appDir + ",filename=" + filename); initMongo(); getFileShowPath(appDir); gridFS.remove(filename); baseResult.setError("删除成功"); baseResult.setErrorCode("0000"); ajaxOut(baseResult.toString(), res); } catch (Exception e) { System.out.println("删除文件异常 ..."); e.printStackTrace(); baseResult.setError("删除文件失败"); baseResult.setErrorCode("1000"); ajaxOut(baseResult.toString(), res); } }private boolean checkForm(HttpServletRequest req, HttpServletResponse res) { boolean flag = false; if (!ServletFileUpload.isMultipartContent(req)) { baseResult.setError("Error: 表单必须包含 enctype=multipart/form-data"); baseResult.setErrorCode("1000"); ajaxOut(baseResult.toString(), res); flag = true; }return flag; }public ServletFileUpload initFileUpload() { // 配置上传参数 DiskFileItemFactory diskFactory = new DiskFileItemFactory(); // threshold 极限、临界值,即硬盘缓存 1M diskFactory.setSizeThreshold(MEMORY_THRESHOLD); // repository 贮藏室,即临时文件目录 // diskFactory.setRepository(new File(filePath + File.separator + "temp")); ServletFileUpload upload = new ServletFileUpload(diskFactory); // 设置最大文件上传值 upload.setFileSizeMax(MAX_FILE_SIZE); // 设置最大请求值 (包含文件和表单数据) upload.setSizeMax(MAX_REQUEST_SIZE); return upload; }@SuppressWarnings("deprecation") public void initMongo() { //用户名密码校验写法3.0后 //MongoCredentialcredential = MongoCredential.createCredential("root", "qyqapp", "123456".toCharArray()); //mongo = new MongoClient(new ServerAddress("192.168.122.203", 27017),Arrays.asList(credential)); mongo = new MongoClient(new ServerAddress("192.168.122.203", 27017)); db = mongo.getDB("qyqapp"); }public String getFileShowPath(String appDir) { String fileShowPath = ""; if (appDir != null && !"".equals(appDir)) { gridFS = new GridFS(db, appDir); fileShowPath = showPath + "/" + appDir; } else { gridFS = new GridFS(db); fileShowPath = showPath; }return fileShowPath; }public String getNewFileName(String type, String oldFileName) { String newFileName; if (NOT_RENAME.equals(type)) { newFileName = oldFileName; } else { newFileName = Long.toString(System.currentTimeMillis()) + oldFileName.substring(oldFileName.lastIndexOf(".")); }return newFileName; }public GridFSInputFile saveFile(FileItem item, String newFileName) throws Exception { GridFSInputFile file = gridFS.createFile(item.getInputStream()); file.setChunkSize(DEFAULT_CHUNK_SIZE); file.setFilename(newFileName); file.setContentType(newFileName.substring(newFileName.lastIndexOf("."))); file.put("uploadDate", new Date()); file.save(); return file; }/** * <一句话功能简述> <功能详细描述> 封装返回json数据 * * @param strContent [参数说明] * * @return void [返回类型说明] * @exception throws [违例类型] [违例说明] * @see [类、类#方法、类#成员] */ public final void ajaxOut(String strContent, HttpServletResponse res) { System.out.println(strContent); res.setContentType("text/html; charset=UTF-8"); res.setCharacterEncoding("UTF-8"); res.setHeader("Access-Control-Allow-Origin", "*"); PrintWriter out; try { out = res.getWriter(); out.print(strContent); out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } } }

测试页面:
Insert title here method:
appDir:
type:
filename:



3、注意事项
(1)可以使用
GridFSInputFile file = gridFS.createFile(item.getInputStream()); file.setChunkSize(DEFAULT_CHUNK_SIZE);

设置分片的大小。我这里设置的是小于10M不分片。想看上传的文件是否分片可以使用可视化工具查看 mongodb+GridFS文件的上传下载删除
文章图片
默认是256kb

    推荐阅读