1、背景
最近项目使用mongDB做文件服务器,用于文件存储。所以稍微研究了下mongDB API写了个简单文件上传下载删除示例
2、具体代码
完整demo下载路径:http://download.youkuaiyun.com/detail/szs860806/9846782
代码中有完整注释。这里就不一一赘述了。我这里使用的是fileupload做的上传。这里是使用的jar:
代码是用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; // 3MB
private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB
private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB
private 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<FileItem> fileItems = upload.parseRequest(req);
if (fileItems != null && fileItems.size() > 0)
{
initMongo();// 初始化mongoDB
String fileShowPath = getFileShowPath(appDir);// 获取展示地址
List<FileInfo> fileList = new ArrayList<FileInfo>();
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后
// MongoCredential credential = 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();
}
}
}
测试页面:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
method:<select id="method">
<option value="upload">upload</option>
<option value="delete">delete</option>
<option value="downloadFile">downloadFile</option>
</select><br>
appDir:<input type="text" id="appDir" value="flow"><br>
type:<select id="type"><option value="0">0</option><option value="1">1</option></select><br>
filename:<input type="text" value="" id="filename"><br>
<form name="form1" action="" method="post" enctype="multipart/form-data" οnsubmit="updateAction();">
<input type="file" name="file" id="file"><br/>
<input type="submit" value="提交">
</form>
<script type="text/javascript">
function updateAction(){
var method = document.getElementById("method").value;
var appDir = document.getElementById("appDir").value;
var type = document.getElementById("type").value;
var filename = document.getElementById("filename").value;
document.form1.action="/qyqUpload/iupload.do?appDir="+appDir+"&type="+type+"&method="+method+"&filename="+filename
}
</script>
</body>
</html>
3、注意事项
(1)可以使用GridFSInputFile file = gridFS.createFile(item.getInputStream());
file.setChunkSize(DEFAULT_CHUNK_SIZE);
设置分片的大小。我这里设置的是小于10M不分片。想看上传的文件是否分片可以使用可视化工具查看
默认是256kb