应用案例——文件上传
form.html + UploadServlet
通过该案例了解文件上传时服务器如何获取表单传送的文件信息。
案例使用了form.html而非.jsp来进行展示,说明不需要展示动态页面,而且如果UploadServlet中有内容需要展示在浏览器中,那么是通过输入输出流的方式在浏览器中进行显示。
正如上面分析,form.html内容很简单,
<form action="UploadServlet" method="post" enctype="multipart/form-data">
...
<td>上传者</td>
<td><input type="text" name="name"></td>
...
<td>上传文件</td>
<td><input type="file" name="myfile"></td>
...
</form>
在上传文件
的输入框旁边现在就多了一个浏览...
的按钮用于选择文件夹,当点击上传
按钮就会跳转到UploadServlet。此时,无论是表单中的文本name
还是表单myfile
都会被保存到request中的消息体中。
这个消息体需要进行处理,首先登场的是DiskFIleItemFactory
类。它的最终目的是将消息实体中的每一个文件封装成单独的FileItem
对象(但是案例中实现该功能的确实ServletFileUpload
这个类)。FileItem对象中可能保存的是文本,也可能保存的是文件,我们可以通过isFormField()
方法来区分,并根据结果来进行区分操作。
DiskFileItemFactory factory = new DiskFileItemFactory();
//将上传文件以临时文件形式保存在路径f中。
File f = new File("e:\Target");
//为了突出重点,这里假设该路径存在,不进行检测
factory.setRepository(f);
ServletFileUpload fileupload= new ServletFileUpload(factory);
fileupload.setHeaderEncoding("gbk");
List<FileItem>fileitems = fileupload.parseRequest(request);
梳理一下上面这段代码,最核心的类是ServletFileUpload
,它的实例是fileupload。它分为有参数和无参数两种构造方法,这里使用的是有参数的构造方法。使用一个DiskFileItemFactory
类的实例对象作为参数。然后再调用parseRequest()
方法来将消息实体中的每一个文件封装成单独的FileItem对象。
接下来对fileitems进行判断,如果是文件而非普通字段,那么可以通过getName()方法获得文件名:
if (! fileitem.isFormField()){
String filename = fileitem.getName();
...
}