文件的上传下载 Upload&Download |
---|
(一)文件的上传
文件的上传即将本地文件上传到远程服务器端
文件上传的流也需要放到一个表单中
2、文件上传的表单的要求
- 文件上传的表单需要设置的请求方式是POST请求
文件上传的表单项的type属性需要指定为:file
<input type="file" name="photo">
给form表单添加一个enctype属性
该属性的默认值是:application/x-www-form-urlencoded 当是该属性值时表单中的内容会使用URL进行编码 我们上传文件需要将该属性的值修改为:multipart/form-data 使用该值时表单中的表单项会以一个多部件的形式提交到服务器, 一个表单项就是一个多部件,而且各个多部件之间使用像------WebKitFormBoundarypkeMFtY9i1D0COuu这样的分隔符进行分割
3 Upload装备三个核心类 七个核心方法
FileUpload是Apache为我们提供的专门用来进行文件上传和下载的工具类
使用FileUpload需要导入以下jar包
commons-fileupload-1.3.1.jar
commons-io-2.5.jar
核心类:
<1>DiskFileItemFactory
创建工厂类实例
<2>ServletFileUpload
创建解析器类实例
<3>FileItem
通过解析器解析请求之后得到的没个多部件就对应一个个FileItem对象
核心方法:
isFormField()
用来判断表单项是否是一个普通表单项
getFieldName()
用来获取表单项中的name属性值
getString(String encoding)
用来获取表单项中输入的value属性值,方法中传入一个字符集
getContentType()
用来获取文件的类型,是一个MIME值
getName()
用来获取文件名
getSize()
用来获取文件的大小,单位字节
write(File file)
将文件写到某个地方
具体实现:
jsp页面的实现如下:
<body>
<form action="${pageContext.request.contextPath}/uploadServlet" method="post" enctype="multipart/form-data">
<center>
<table height="250px">
<tr>
<td>用户名:</td>
<td><input type="text" name="userName"/></td>
</tr>
<tr>
<td>文件1:</td>
<td><input type="file" name="file1"/></td>
</tr>
<tr>
<td>文件2:</td>
<td><input type="file" name="file2"/></td>
</tr>
<tr>
<td>文件3:</td>
<td><input type="file" name="file3"/></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="确定"/></td>
</tr>
<tr>
<td>
<a href="${pageContext.request.contextPath }/downLoadServlet">更多下载资源</a>
</td>
</tr>
<tr>
<td><span style="color: red">${requestScope.msg }</span></td>
</tr>
<tr>
<td><span style="color: green">${requestScope.mesgsuccess }</span></td>
</tr>
</table>
</center>
</form>
</body>
实现文件上传的Servlet如下:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*用此方式获取不到表单提交参数正确的实现如下
String username = request.getParameter("username");
String file1 = request.getParameter("file1");
String file2 = request.getParameter("file2");
String file3 = request.getParameter("file3");
System.out.println(username+file1+file2+file3);*/
//1.创建工厂类实例
DiskFileItemFactory factory=new DiskFileItemFactory();
//2.创建解析器类实例
ServletFileUpload fileUpload=new ServletFileUpload(factory);
//设置单个文件的大小不超过200KB
fileUpload.setFileSizeMax(1024*400*10);
//设置文件的总大小不超过450KB
fileUpload.setSizeMax(1024*400*30);
//3.解析请求
try {
List<FileItem> parseRequest = fileUpload.parseRequest(request);
for (FileItem fileItem : parseRequest) {
/*核心方法:
* isFormField():用来判断表单项是否是一个普通表单项
* getFieldName():用来获取表单项中的name属性值
* getString(String encoding):用来获取表单项中输入的value属性值,方法中传入一个字符集
*
* getContentType():用来获取文件的类型,是一个MIME值
* getName():用来获取文件名
* getSize():用来获取文件的大小
* write(File file):将文件写到硬盘上
*/
if(fileItem.isFormField()) {
//证明是一个普通表单项
//获取name属性值
String fieldName = fileItem.getFieldName();
//获取用户输入的值设置乱码
String inputValue = fileItem.getString("UTF-8");
System.out.println("表单项的name属性值为:"+fieldName);
System.out.println("表单项中用户输入的值是 :"+inputValue);
}else {
//证明提交类型为文件 获取文件的类型
String contentType = fileItem.getContentType();
//获取文件名
String name = fileItem.getName();
//截取文件名 不要前面的路径(因为ie浏览器会带路径)
if(name.contains("\\")) {
name=name.substring(name.lastIndexOf("\\")+1);
}
//获取单个文件的大小
long fileSize = fileItem.getSize();
System.out.println("文件的类型是:"+contentType);
System.out.println("文件名是:"+name);
System.out.println("文件的大小是:"+fileSize+"字节");
//获取服务器端upload目录的真实路径(将文件上传到服务器)
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/upload");
//创建目录
File file=new File(realPath);
if(!file.exists()){
//创建这个目录
file.mkdirs();
}
//使用UUID生成一个全球唯一的字符串
String uuid = UUID.randomUUID().toString().replace("-","");
//将上传的文件写到服务器端的upload目录中
fileItem.write(new File(realPath+"/"+uuid+"_"+name));
}
}
} catch (FileSizeLimitExceededException e) {
//e.printStackTrace();
//设置一个错误消息
request.setAttribute("msg", "单个文件不要超过4MB!");
request.getRequestDispatcher("/index.jsp").forward(request, response);
} catch (SizeLimitExceededException e) {
// e.printStackTrace();
//设置一个错误消息
request.setAttribute("msg", "总文件大小不要超过12MB!");
request.getRequestDispatcher("/index.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}
request.setAttribute("mesgsuccess", "上传文件成功!!");
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
(二)文件的下载
文件的下载即将文件从服务器端下载到本地
文件的下载只需要将文件的地址作为一个超链接显示在浏览器端,然后点击超链接即可完成下载
但是这样做对于支持该文件格式的浏览器来说并不会下载该文件,而是直接将这个文件打开;
而且我们也不可以给文件设置下载的权限,所以我们通常将被下载的文件放到WEB-INF下,通过
Servlet来下载文件
1.通过在Servlet下载文件
1)创建一个输入流
2)设置两个响应头
3)使用输出流输出到浏览器端
2.具体实现:
Servlet实现如下:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取文件在服务器端的真实路径
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/WEB-INF/download/相见恨晚.mp3");
//1.创建一个输入流
InputStream is = new FileInputStream(realPath);
String fileName = "相见恨晚.mp3";
//获取用户使用的浏览器
String header = request.getHeader("User-Agent");
if(header.contains("Firefox")){
//证明使用的是火狐浏览器
//对应火狐浏览器,我们需要进行BASE64编码
fileName = "=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes())+"?=";
}else{
//对文件名进行URL编码
fileName = URLEncoder.encode(fileName, "UTF-8");
}
//2.设置两个响应头
//①设置文件的类型,是一个MIME值
//获取文件的MIME值
String mimeType = servletContext.getMimeType(realPath);
System.out.println(mimeType);
response.setHeader("Content-Type", mimeType);
//②设置浏览器怎样处理当前文件
response.setHeader("Content-Disposition", "attachment; filename="+fileName);
//3.使用输出流将文件输出到浏览器
ServletOutputStream os = response.getOutputStream();
//将输入流复制到输出流中
IOUtils.copy(is, os);
//关闭流
is.close();
}