文件上传你分为上传文件和文件下载
1.上传的实现
注意了我们在写上传表单的时候必须声明提交方式为post类型,enctype="multipart/form-data",这样的话才能实现上传。
/* * 需要解决的问题: * 1 必须要把文件存放到WEB-INF目录下,避免用户看到 * 2 文件名相关问题 * 1 有的浏览器会传递绝对路径到name中,我们只需要进行拆分即可 * 2文件重名问题,我们可以使用uuid * 3文件名乱码问题,我们已经解决了。即request.setCharacterEncoding("utf-8"); * 3 文件打散问题 * 1通过首字符打散 * 2通过时间打散 * 3通过hash打散 * 4上传文件大小限制 * 1单个文件上传大小限制 * 2总文件上传大小限制 * 设置这两个参数时,我们必须在没有解析之前执行。 * 5 缓存大小与临时目录 * * * */ public class FileUploadServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); /* * 我们使用commmons的小工具来进行编码 * 设置jsp页面的enctype= “multipart/form-data“; * 1 创建FileItem工厂 * 2创建ServletFileUpload对象 * 3 解析request得到FileItem * 4对FileItem进行操作 */ String path = request.getSession().getServletContext().getRealPath("/WEB-INF"); //解决缓存大小,要不然你的内存会爆的。 DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(1024 * 10,new File(path + "/" + "tmp2") ); ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory); List<FileItem> l = null; try { l = fileUpload.parseRequest(request); FileItem f2 = l.get(0); //解决文件存放在WEN_INF目录下问题 path = path + "/tmp"; //解决浏览器传递绝对路径问题 String name = f2.getName(); int i = name.lastIndexOf("/"); if(i != -1) { name = name.substring(i); } //解决文件重名问题 name = (UUID.randomUUID().toString().replace("-","").trim()) + name; //文件打散问题解决方法演示之hash打散 int has = name.hashCode(); //转换位16进制位,我们使用前两个值来判断 String hex = Integer.toHexString(has); path = path + "/" + hex.charAt(0) + "/" + hex.charAt(2) ; File file = new File(path); if(! file.exists()) { file.mkdirs(); } f2.write(new File(path + "/" + name)); request.setAttribute("msg","恭喜你,上传成功了!"); request.getRequestDispatcher("/index.jsp").forward(request, response); } catch (Exception e) { request.setAttribute("msg",e.getMessage()); request.getRequestDispatcher("/index.jsp").forward(request, response); } } }
2.文件的下载
下载文件是我们必须来设置两个响应头,设置Content-Disposition:它的默认值为inline,表示在浏览器窗口中打开!attachment;filename=xxx要不然我们输出的内容不会弹出保存框,只会显示在浏览器中。
设置Content-Type:你传递给客户端的文件是什么MIME类型
然后我们就可以new一个输入流来读取本地硬盘中的文件,在输出到ServleoutputStream中
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- /*
- * 设置两个响应头
- * 1Content-Type:你传递给客户端的文件是什么MIME类型
- * 2Content-Disposition:它的默认值为inline,表示在浏览器窗口中打开!attachment;filename=xxx
- *
- * 需要解决的的问题:
- * 1 下载文件名中文乱码问题
- * 解决方法:
- * 针对不同的浏览器使用不同的编码方式 火狐浏览器使用的是Base64编码,其他浏览器一般都是使用url编码
- */
- String mimeType = request.getSession().getServletContext().getMimeType("\WEB-INF\tmp\2\5\"
- + "87bd61a4b7c346a5a2e6c072de84acda5.JdbcUtils处理多线程并发访问问题.avi");
- //解决文件名乱码问题
- String filename = "87bd61a4b7c346a5a2e6c072de84acda5.JdbcUtils处理多线程并发访问问题.avi";
- filename = encoding(filename, request);
- //两个请求头
- response.setHeader("Content-Type",mimeType);
- response.setHeader("Content-Disposition","attachment;filename=" + filename);
- ServletOutputStream out = response.getOutputStream();
- String path = request.getSession().getServletContext().getRealPath("\WEB-INF\tmp\2\5\"
- + "87bd61a4b7c346a5a2e6c072de84acda5.JdbcUtils处理多线程并发访问问题.avi");
- File file = new File(path);
- FileInputStream inputStream = new FileInputStream(file);
- IOUtils.copy(inputStream, out, 1024*1024);
- }
- private String encoding(String filename,HttpServletRequest req) throws UnsupportedEncodingException {
- String user_agent = req.getHeader("User-Agent");
- String encodingFileName = null;
- if(user_agent.contains("Firefox")) {
- //按道理来说应该使用 BASE64Encoder进行编码,但是不知道为什么不能成功
- /*BASE64Encoder base64Encoder = new BASE64Encoder();
- encodingFileName = "=?utf-8?B?"
- + base64Encoder.encode(filename.getBytes("utf-8"))
- + "?=";*/
- //那我们只能使用这种方式了
- encodingFileName = new String(filename.getBytes("UTF-8"), "ISO-8859-1");
- }
- else {
- encodingFileName = URLEncoder.encode(filename,"utf-8");
- }
- return encodingFileName;
- }
- }