1.文件上传的相关API
1.1 Fileltem接口
Fileltem接口在Commons-FileUpload组件中被实现,其主要用于封装单个表单字段元素的数据,一个表单字段元素对应一个Fileltem对象。而Fileltem接口实现的类Fileltem类,其实现Serializable接口,Fileltem类定义了许多获取表单字段元素的方法,如:
(1)boolean isFormFiled()方法
isFormFiled()方法用于判断Fileltem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通文本表单字段,则返回true,否则返回false。
(2)String getName()方法
getName()方法用于获得文件上传字段中的文件名。若Fileltem类对象对应的是普通文本表单字段,将返回null,否则,返回一个字符串类型的结果。但通过不同浏览器上传的文件,获取到的完整路径和名称都是不一样的。
(3)String getFieldName()方法
getFieldName()方法用于获得表单字段元素描述头的name属性值,也是表单标签name属性的值。
(4)void write(File file)方法
write()方法用于将Fileltem对象中保存的主体内容保存到某个指定的文件中。若Fileltem对象中的主题内容是保存在某个临时文件中,该方法顺利完成后,临时文件有可能会被清除。
(5)String getString()方法
getString()方法用于将Fileltem对象中保存的数据流内容以一个字符串返回,它有两个重载的定义形式:
1).public String getString() :使用了默认的字符集编码将主体内容转换成字符串
2).public String getString(java.lang.String encoding):使用参数指定的字符集编码将主体内容转换成字符串,若在读取普通表单字段元素内容时出现中文乱码现象,则可以调用。
(6)String getContentType()方法
getContentType()方法用于获得上传文件的类型,即表单字段元素描述头属性“Content-Type”的值,若Fileltem类对象对应的是普通表单字段,该方法返回null。
(7)boolean isInMemory()方法
isInMemory()方法用于判断Fileltem对象封装的数据内容是存储在内存中,还是存储在临时文件中,若存储在内存中则返回true,否则返回false。
(8)void delete()方法
delete()方法用于清空Fileltem类对象中存放的主体内容,若主体内容被保存在临时文件中,delete()方法将删除该临时文件。
(9)InputStream getInputStream()方法
getInputStream()方法以流的形式返回上传文件的数据内容。
(10)long getSize()方法
getSize()方法返回该上传文件的大小(以字节为单位)。
1.2 DiskFileltemFactory类
DiskFileltemFactory类用于将请求消息实体中的每一个文件封装成单独的Fileltem对象。
常用方法:
(1)Filetltem createltem(String fieldName,String contentType,boolean isFormField,String fileName)方法
用于将请求消息实体创建成Fileltem类型的实例对象
(2)setSizeThreshold(int sizeThreshold)和getSizeThreshold()方法
getSizeThreshold()方法用于设置是否将上传文件以临时文件的形式保存在磁盘的临界值。
(3)setRepository(File repository)和getRepository()方法
1.3 ServletFileUpload()类
ServletFileUpload类是Apache组件文件上传的核心高级类,通过使用parseRequest(HttpServletRequest)方法可以将HTML中每个表单提交的数据封装成一个Fileltem对象,然后以List列表的形式返回。该类的常用方法,如下:
(1)setSizeMax(long sizeMax)和getSizeMax()方法
getSizeMax()方法继承自FileUploadBase类,用于设置请求消息实体内容(即所有上传数据)的最大尺寸限制,以防止客户端恶意上传超大文件来浪费服务器端的存储空间,还用于读取请求消息实体内容所允许的最大值。
(2)setFileSizeMax(long fileSizeMax)和getFileSizeMax()方法
getSizeMax()方法继承自FileUploadBase类,用于设置单个上传文件的最大尺寸限制,以防止客户端恶意上传超大文件来浪费服务器端的存储空间,对应的getFileSizeMax()方法用于获取单个上传文件所允许的最大值。
(3)parseRequest(javax.servlet.http.HttpServletRequest req)
parseRequest()方法是ServletFileUpload类的重要方法。
(4)getItemIterator(HttpServletRequest request)
getItemIterator()方法和parseRequest()方法的作用基本相同。
(5)isMultipartContent(HttpServletRequest req)
isMultipartContent()方法用于判断请求消息中的内容是否是“multpart/form-data”类型,如果是,则返回true,否则返回false,该方法时一个静态方法,不用创建ServletFileUpload类的实例对象即可被调用。
(6)getFileItemFactory()和setFileItemFactory(FileItemFactory factory)
两个方法都继承FileUpload类,分别读取和设置fileItemFactory属性
(7)setHeaderEncoding(String encoding)和getHeaderEncoding()方法
两个方法都继承自FileUploadBase类,用于设置和读取字符编码。
1.3 实现文件上传
1.创建项目,导入JAR包
在eclipse中创建一个chapter12的Web项目,在项目的WEB-INF/lib目录下导入JAR包commons-fileupload1.3.1.jar和commons-io-2.4.jar,并发布到类路径下。
2. 创建上传页面
在chapter12项目的webContent目录下创建一个名称为form的jsp页面,该页面用于提供上传文件的Form表单,要注意From表单的enctype属性值要设置为“multpart/form-data”,method三下载要设置为“post”,并将其action的属性值设置为“UploadServlet”。form.jsp代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传</title>
</head>
<body>
<form action="upload" method="post"
enctype="multipart/form-data">
<table width="600px">
<tr>
<td>上传者</td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>上传文件</td>
<td><input type="file" name="myfile" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="上传" /></td>
</tr>
</table>
</form>
</body>
</html>
3.创建Servlet
在项目的src项目下创建一个名称为cn.itcast.fileupload的包,在该包中编写一个UploadServlet类,用于获取表单及其上传文件的信息,代码如下:
package cn.itcast.fileupload;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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;
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
try {
DiskFileItemFactory factory = new DiskFileItemFactory();
File f = new File("D:\\Temp");
if (!f.exists()) {
f.mkdirs();
}
factory.setRepository(f);
factory.setSizeThreshold(1024*1024);
ServletFileUpload fileupload = new ServletFileUpload(factory);
fileupload.setHeaderEncoding("utf-8");
List<FileItem> fileitems = fileupload.parseRequest(request);
for (FileItem fileitem : fileitems) {
boolean flag = fileitem.isFormField();
if (flag) {
String name = fileitem.getFieldName();
if (name.equals("username")) {
if ( !fileitem.getString().equals("")) {
String value = fileitem.getString("utf-8");
response.getWriter().print("从网页上传者:"+ value + "<br/>");
}
}
}else {
String filename = fileitem.getName();
if (filename != null && !filename.equals("")) {
response.getWriter().print("从网页上传文件名称:"+ filename + "<br/>");
filename = filename.substring(filename.lastIndexOf("\\")+1);
filename = UUID.randomUUID().toString()+"_"+filename;
String webPath="/upload";
String filepath = getServletContext().getRealPath(webPath+filename);
File file = new File(filepath);
file.getParentFile().mkdirs();
file.createNewFile();
InputStream in = fileitem.getInputStream();
FileOutputStream out = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = in.read(buffer))>0) {
out.write(buffer,0,len);
}
in.close();
out.close();
fileitem.delete();
response.getWriter().print("文件上传成功"+"<br/>");
}
}
}
}catch(FileUploadException e) {
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
4.启动项目,查看运行结果
启动Tomcat服务器,运行结果如下所示:
在form表单中填写信息,选择好要上传的文件并单击【上传】后,显示结果如下:
2 文件下载
1.实现文件下载
1.创建下载页面
在chapter12项目的webContent目录下创建一个名称为download的jsp页面,该页面中编写了一个用于下载的链接,代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.net.URLEncoder"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件下载</title>
</head>
<body>
<a href="/chapter12/download?filename=1.png">文件下载-不是中文</a>
<br/><br/><br/>
<a href="/chapter12/download?filename=<%=URLEncoder.encode("2.jpg","utf-8")%>">文件下载 -是中文</a>
<br/><br/><br/>
<a href="/chapter12/download?filename=2.jpg">文件下载-中文之第二种解决方法</a>
<br/><br/><br/>
</body>
</html>
2.创建Servlet
在cn.itcast.fileupload的包中编写一个DownloadServlet类,用于设置所要下载的文件及文件再浏览器的打开方式,代码如下:
package cn.itcast.fileupload;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String filename = request.getParameter("filename");
filename = new String(filename.getBytes("iso-8859-1"),"utf-8");
String fileType = getServletContext().getMimeType(filename);
response.addHeader("Content-type", fileType);
String folder = "/download/";
InputStream in = getServletContext().getResourceAsStream(folder+filename);
OutputStream out = response.getOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = in.read(buffer))!=-1) {
out.write(buffer,0,len);
}
out.close();
in.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
3.创建下载目录及文件
在项目的WebContent目录下创建一个名称为download的文件夹(Folder),在该文件夹下放置一个名为“1.jpg”的图片文件,如图:
4.启动项目,查看结果
启动Tomcat服务器,运行结果如下所示: