文章目录
1 实验目的
- 掌握通过Servlet实现文件上传下载功能;
- 重点掌握commons-fileupload.jar接收浏览器上传文件,实现上传功能;
2 实验注意事项
首先文件上传表单的数据也是被封装到request对象中的。
request.getParameter(String)方法获取指定的表单字段字符内容,但文件上传表单已经不在是字符内容,而是字节内容,所以失效。
这时可以使用request的getInputStream()方法获取ServletInputStream对象,它是InputStream的子类,这个ServletInputStream对象对应整个表单的正文部分(从第一个分隔线开始,到最后),这说明需要的解析流中的数据。
当然解析它是很麻烦的一件事情,而Apache已经帮我们提供了解析它的工具:
commons-fileupload.jar
。
该组件由多个类共同组成,使用该组件实现文件上传功能,只需要了解和使用其中三个类:DiskFileUpload
、FileItem
、FileUploadException
。
使用fileupload组件的步骤如下:
- 创建工厂类DiskFileItemFactory对象:
DiskFileItemFactory factory = new DiskFileItemFactory()- 使用工厂创建解析器对象:
ServletFileUpload fileUpload = new ServletFileUpload(factory)- 使用解析器来解析request对象:
List list = fileUpload.parseRequest(request)
FileItem类,它才是最终要的结果。一个FileItem对象对应一个表单项(表单字段)。
一个表单中存在文件字段和普通字段,可以使用FileItem类的isFormField()方法来判断表单字段是否为普通字段,如果不是普通字段,那么就是文件字段了。
- String getName():获取文件字段的文件名称;
- String getString():获取字段的内容,如果是文件字段,那么获取的是文件内容,当然上传的文件必须是文本文件;
- String getFieldName():获取字段名称,例如:,返回的是username;
- String getContentType():获取上传的文件的类型,例如:text/plain。
- int getSize():获取上传文件的大小;
- boolean isFormField():判断当前表单字段是否为普通文本字段,如果返回false,说明是文件字段;
- InputStream getInputStream():获取上传文件对应的输入流;
- void write(File):把上传的文件保存到指定文件中。
3 实验任务与步骤
任务描述:
利用Apache公司的commons-fileupload.jar接收浏览器上传文件,实现文件上传功能。
3.1 导入Jar包
3.2 编写FileUploadServlet.java
package exp06.bean;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
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.DiskFileUpload;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
public class FileUploadServlet extends HttpServlet {
public FileUploadServlet() {
super();
}
public void destroy() {
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//设置保存上传文件的目录
String uploadDir = "d:/upfile"; //文件上传后的保存路径
out.println("上传文件存储目录:"+uploadDir);
File fUploadDir = new File(uploadDir);
if(!fUploadDir.exists()){
if(!fUploadDir.mkdir()){
out.println("无法创建存储目录d:/upfile!");
return;
}
}
if (!DiskFileUpload.isMultipartContent(request)){
out.println("只能处理multipart/form-data类型的数据!");
return;
}
DiskFileUpload fu = new DiskFileUpload();
fu.setSizeMax(1024*1024*200);//最多上传200M数据
fu.setSizeThreshold(1024*1024);//超过1M的数据采用临时文件缓存
//fu.setRepositoryPath(...); //设置临时文件存储位置(如不设置,则采用默认位置)
fu.setHeaderEncoding("utf-8");//设置上传的文件字段的文件名所用的字符集编码
List fileItems = null;//创建文件集合,用于保存浏览器表单传来的文件
try
{
fileItems = fu.parseRequest(request);
}
catch(FileUploadException e)
{
out.println("解析数据时出现如下问题:");
e.printStackTrace(out);
return;
}
//下面通过迭代器逐个将集合中的文件取出,保存到服务器上
Iterator it = fileItems.iterator(); //创建迭代器对象it
while (it.hasNext())
{
FileItem fitem = (FileItem) it.next(); //由迭代器取出文件项
if (!fitem.isFormField()) //忽略其他不属于文件域的那些表单信息
try{
String pathSrc = fitem.getName();
//文件名为空的文件项不处理
if(pathSrc.trim().equals(""))continue;
//确定最后的"\"位置,以此获取不含路径的文件名
int start = pathSrc.lastIndexOf('\\');
//获取不含路径的文件名
String fileName = pathSrc.substring(start + 1);
File pathDest = new File(uploadDir, fileName); //构建目标文件对象
fitem.write(pathDest); //将文件保存到服务器上
}
catch (Exception e)
{
out.println("存储文件时出现如下问题:");
e.printStackTrace(out);
return;
}
finally //总是立即删除保存表单字段内容的临时文件
{
fitem.delete();
}
}
response.sendRedirect("./fileupload/fileupload_list.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
doGet(request,response);
}
public void init() throws ServletException {
}
}
3.3 编写web.xml
<servlet>
<servlet-name>FileUploadServlet</servlet-name>
<servlet-class>exp06.bean.FileUploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileUploadServlet</servlet-name>
<url-pattern>/FileUploadServlet</url-pattern>
</servlet-mapping>
3.4 编写fileupload.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>文件上传</title>
</head>
<body>
<h1>文件上传</h1>
<form name="uploadform" method="post" action="../../FileUploadServlet" ENCTYPE="multipart/form-data">
文件1:<input type="file" name="file1"><hr/>
文件2:<input type="file" name="file2"><hr/>
文件3:<input type="file" name="file3"><hr/>
<input type="submit" name="submit" value="开始上传"/><hr/>
</form>
</body>
</html>
3.5 编写fileuploadList.jsp
<%--
Document : fileuploadList
Created on : 2018-10-6, 14:33:41
Author : Administrator
--%>
<%@ page contentType="text/html; charset=utf-8" import="java.io.*" %>
<html>
<head> <title>文件目录</title></head>
<body>
<font size=4 color=red>已上传的文件目录列表</font><br>
<font size=5 color=blue>
<%
String path = "d:/upfile";
File fl = new File(path);
File filelist[] = fl.listFiles();
out.println("服务器上上传文件的保存路径:"+path+"<br><br>");
for(int i=0; i < filelist.length; i++)
{
out.println((i+1)+":"+filelist[i].getName()+" <br>");
//如果是图片文件,可用以下语句显示图片。
//out.println("<img src=images\\"+filelist[i].getName()+"><br><br>");
}
%>
</body>
</html>
3.6 测试运行
http://localhost:8081/Study/jsp/exp06/fileupload.html
4 思考题
- 了解和使用其中三个类:DiskFileUpload、FileItem、FileUploadException ;
- 结合本案例理解文件上传过程。
5 实验总结
本实验实现了:
- JSP页面提交文件数据到Servlet;
- Servlet将浏览器上传的文件保存到指定文件夹;
- 设计JSP页面,显示文件上传结果。
6 扩展实验
使用文件上传功能实现图片外链网站和资源托管网站:
https://blog.csdn.net/zhaoxuyang1997/article/details/82912339