JavaWeb基础—上传与下载
2017-04-13 20:25
148 查看
1.上传(不能使用BaseServlet):
上传的作用,略
上传的要求(对表单和Servlet都有要求):
1.必须使用表单,而不能是超链接,method="post" 文件明显不能get把参数带在后面
2.必须使用多部件表单数据 enctype="multipart/form-data"
3.表单中必须添加文件表单项 input type="file" name="xxx"
4.凡是带文件的表单的所有(所有!)数据都不能用getParameter()方法获取,带了enctype
就无法使用此方法,而是使用getInputStream() 返回整个请求体
多部件表单的体:
1.一个表单项一个部件
2.一个部件中包含请求头、空行、请求体
3.普通表单项:一个头 Content-Disposition name=“xxx” 即表单项的名字,体就是表单项的值
文件表单项:包含两个头:Content-Disposition name=“xxx”,表单项名称,和一个filename="xxx"即文件名称
Content-Type:上传文件的MIME类型
commons-fileupload.jar包登场,他有一个io的依赖包
它可以帮我们解析request中的数据,一个表单数据封装到一个items对象中,调用fileItems的方法即可
上传三步:
1.工厂 DiskFileItemFactory
2.解析器 ServletFileUpload
3.表单项 FileItem
创建工厂 有构造器
创建解析器 给一个工厂,就可以new
得到表单项 使用解析器得到集合数据
给一个request List<FileItem> FileItemList = sfu.parseRequest(request);
给出一个小例子:
JSP页面:
Servlet页面:
上传的细节:
1.文件必须保存到WEB-INF下(当然C.D.E盘都可以,但强烈不建议),目的是为了不让浏览器直接访问
2.文件名称相关:有的是绝对路径,需要进行切割(切割文件名过来),
部分浏览器(IE6,遨游之类)这样
Sting filename = f2.getName();
int index = filename.lastIndexOf("\\");
if(index != -1){
String filename1 = filename.subString(index+1);
}
3.乱码问题:文件的名称乱码等都交给FileUpload来处理,使用时告诉它编码,request.setCharaterEncoding("UTF-8");
fileUpload会自动调用处理
当然,解析器也提供了一个方法
ServletFileUpload.setHeaderEncoding();内部的方法,优先级高
4.处理重名问题,为每个文件名称添加前缀(UUID),处理重名问题
filename = CommonUtils.uuid()+"_"+filename;使用客户的文件名称再加我们的不重复前缀
5.目录打散问题:不能在一个文件夹下存放过多文件
首字母打散:如文件名称叫abc.txt 则保存到B目录下,不存在则创建
局限也明显,中文等的太多复杂
时间打散:使用当前日期作为目录,一天一个文件夹
局限性:有时候周末目录爆满,工作日空空如也
哈希打散(推荐):任何对象都有一个hashCode()方法,得到一个INT值
得到哈希值
把Int值转换成十六进制
获取十六进制的前两位用来生成目录
目录为两层,例如文件名 1A2B3C 生成目录 1/A/文件名
最多可以生成INT的范围,4字节32位,8位十六进制
最多42亿
局限性体现在人工不知道在哪,找起来麻烦,但计算机很清楚
切割文件名->加UUID->得到文件名的哈希值->Integer.toHexString()
->使用String.cahrAt()拿出构建目录的目录名+root文件路径("/WEB-INF/files/") mkdirs
6.上传文件大小限制:单个文件大小限制
整个请求大小限制
解析器有相关的方法:sfu.setFilesizeMax(100*1024);100KB
必须放在解析之前
如果超出限制,在解析时会抛出异常
限制整个表单请求大小 sfu.setSizeMax();也是解析前执行
7.缓存大小与临时目录
1.缓存大小:超出多大才向硬盘保存,默认10KB
2.向硬盘的什么目录保存
DiskFileItemFactory(int sizeThreshold, File repository)
使用此构造器,可以指定缓存与临时目录
2.下载:下载就是客户端响应字节数据
下载的要求:
两个头一个流
Content-Type (什么类型)
Content-Dispositon (默认值是inline,浏览器能打开他就打开,图片,文字等)
要弹下载框需要设置为 accathment;filename=xxx
流就是要下载的文件数据
下载的细节:
显示在下载框的中文名称会出现乱码
大部分主流浏览器都使用URL编码
通用解决方案:frameName = new String(filename.getBytes(""),"");
一个小工具类(此处略) filenameEncoding方法
详细步骤:
借用苍狼大神的示例:
View Code
上传的作用,略
上传的要求(对表单和Servlet都有要求):
1.必须使用表单,而不能是超链接,method="post" 文件明显不能get把参数带在后面
2.必须使用多部件表单数据 enctype="multipart/form-data"
3.表单中必须添加文件表单项 input type="file" name="xxx"
4.凡是带文件的表单的所有(所有!)数据都不能用getParameter()方法获取,带了enctype
就无法使用此方法,而是使用getInputStream() 返回整个请求体
多部件表单的体:
1.一个表单项一个部件
2.一个部件中包含请求头、空行、请求体
3.普通表单项:一个头 Content-Disposition name=“xxx” 即表单项的名字,体就是表单项的值
文件表单项:包含两个头:Content-Disposition name=“xxx”,表单项名称,和一个filename="xxx"即文件名称
Content-Type:上传文件的MIME类型
commons-fileupload.jar包登场,他有一个io的依赖包
它可以帮我们解析request中的数据,一个表单数据封装到一个items对象中,调用fileItems的方法即可
上传三步:
1.工厂 DiskFileItemFactory
2.解析器 ServletFileUpload
3.表单项 FileItem
创建工厂 有构造器
创建解析器 给一个工厂,就可以new
得到表单项 使用解析器得到集合数据
给一个request List<FileItem> FileItemList = sfu.parseRequest(request);
给出一个小例子:
JSP页面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'form1.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="<c:url value='/UploadServlet'/>" method="post" enctype="multipart/form-data"> 用户名:<input type="text" name="username"/><br/> 照 片:<input type="file" name="photo"/><br/> <input type="submit" value="上传"/> </form> </body> </html>
Servlet页面:
package cn.itacast.servlet; import java.io.File; import java.io.IOException; 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.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; public class UploadServlet2 extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); //上传三步,步骤见笔记 DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload sfu = new ServletFileUpload(factory); sfu.setFileSizeMax(100*1024); try{ List<FileItem> FileItemList = sfu.parseRequest(request); FileItem f1 = FileItemList.get(0); FileItem f2 = FileItemList.get(1); System.out.println("普通表单项:"+f1.getFieldName()+"="+f1.getString("UTF-8")); System.out.println("文件表单项:"); System.out.println("文件类型:"+f2.getContentType()); File file = new File("F:/2.jpg"); f2.write(file); }catch(Exception e){ e.printStackTrace(); } } }
上传的细节:
1.文件必须保存到WEB-INF下(当然C.D.E盘都可以,但强烈不建议),目的是为了不让浏览器直接访问
2.文件名称相关:有的是绝对路径,需要进行切割(切割文件名过来),
部分浏览器(IE6,遨游之类)这样
Sting filename = f2.getName();
int index = filename.lastIndexOf("\\");
if(index != -1){
String filename1 = filename.subString(index+1);
}
3.乱码问题:文件的名称乱码等都交给FileUpload来处理,使用时告诉它编码,request.setCharaterEncoding("UTF-8");
fileUpload会自动调用处理
当然,解析器也提供了一个方法
ServletFileUpload.setHeaderEncoding();内部的方法,优先级高
4.处理重名问题,为每个文件名称添加前缀(UUID),处理重名问题
filename = CommonUtils.uuid()+"_"+filename;使用客户的文件名称再加我们的不重复前缀
5.目录打散问题:不能在一个文件夹下存放过多文件
首字母打散:如文件名称叫abc.txt 则保存到B目录下,不存在则创建
局限也明显,中文等的太多复杂
时间打散:使用当前日期作为目录,一天一个文件夹
局限性:有时候周末目录爆满,工作日空空如也
哈希打散(推荐):任何对象都有一个hashCode()方法,得到一个INT值
得到哈希值
把Int值转换成十六进制
获取十六进制的前两位用来生成目录
目录为两层,例如文件名 1A2B3C 生成目录 1/A/文件名
最多可以生成INT的范围,4字节32位,8位十六进制
最多42亿
局限性体现在人工不知道在哪,找起来麻烦,但计算机很清楚
切割文件名->加UUID->得到文件名的哈希值->Integer.toHexString()
->使用String.cahrAt()拿出构建目录的目录名+root文件路径("/WEB-INF/files/") mkdirs
6.上传文件大小限制:单个文件大小限制
整个请求大小限制
解析器有相关的方法:sfu.setFilesizeMax(100*1024);100KB
必须放在解析之前
如果超出限制,在解析时会抛出异常
限制整个表单请求大小 sfu.setSizeMax();也是解析前执行
7.缓存大小与临时目录
1.缓存大小:超出多大才向硬盘保存,默认10KB
2.向硬盘的什么目录保存
DiskFileItemFactory(int sizeThreshold, File repository)
使用此构造器,可以指定缓存与临时目录
2.下载:下载就是客户端响应字节数据
下载的要求:
两个头一个流
Content-Type (什么类型)
Content-Dispositon (默认值是inline,浏览器能打开他就打开,图片,文字等)
要弹下载框需要设置为 accathment;filename=xxx
流就是要下载的文件数据
下载的细节:
显示在下载框的中文名称会出现乱码
大部分主流浏览器都使用URL编码
通用解决方案:frameName = new String(filename.getBytes(""),"");
一个小工具类(此处略) filenameEncoding方法
详细步骤:
文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载 文件下载功能的实现思路: 1.获取要下载的文件的绝对路径 2.获取要下载的文件名 3.设置content-disposition响应头控制浏览器以下载的形式打开文件 4.获取要下载的文件输入流 5.创建数据缓冲区 6.通过response对象获取OutputStream流 7.将FileInputStream流写入到buffer缓冲区 8.使用OutputStream将缓冲区的数据输出到客户端浏览器
借用苍狼大神的示例:
package gacl.response.study; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author gacl * 文件下载 */ public class ResponseDemo02 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { downloadFileByOutputStream(response);//下载文件,通过OutputStream流 } /** * 下载文件,通过OutputStream流 * @param response * @throws FileNotFoundException * @throws IOException */ private void downloadFileByOutputStream(HttpServletResponse response) throws FileNotFoundException, IOException { //1.获取要下载的文件的绝对路径 String realPath = this.getServletContext().getRealPath("/download/1.JPG"); //2.获取要下载的文件名 String fileName = realPath.substring(realPath.lastIndexOf("\\")+1); //3.设置content-disposition响应头控制浏览器以下载的形式打开文件 response.setHeader("content-disposition", "attachment;filename="+fileName); //4.获取要下载的文件输入流 InputStream in = new FileInputStream(realPath); int len = 0; //5.创建数据缓冲区 byte[] buffer = new byte[1024]; //6.通过response对象获取OutputStream流 OutputStream out = response.getOutputStream(); //7.将FileInputStream流写入到buffer缓冲区 while ((len = in.read(buffer)) > 0) { //8.使用OutputStream将缓冲区的数据输出到客户端浏览器 out.write(buffer,0,len); } in.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
View Code
相关文章推荐
- Portal-Basic Java Web 应用开发框架:应用篇(四) —— 文件上传和下载
- java-web文件上传下载
- 跟阿根一起学Java Web开发三:文件上传与文件下载
- [JavaWeb基础] 010.Struts2 下载文件
- javaweb 文件上传和下载
- JavaWeb中struts2实现文件上传下载功能实例解析
- JavaWeb -- 文件上传下载示例
- 22.JavaWeb基础 Strut 1 文件上传
- JavaWeb_13_文件上传下载_演示fileupload
- JavaWeb——文件上传和下载
- Java乔晓松-文件的上传和下载(Web) 2
- Java web中上传和下载详解(下)
- java web 实现上传下载
- JavaWeb——文件上传和下载
- Java Web 开发中文件的上传与下载(FTP/HTTP)
- Java乔晓松-文件的上传和下载(Web)案例
- Java web中上传和下载详解(上)
- Web Application(程序)中的上传打包压缩下载(java)
- JavaWeb——文件上传和下载
- JavaWeb之文件上传与下载&邮件技术(十八)