上传支持
一、Servlet3.0 新特性 概述
Servlet3.0的主要新特性如下三部分:
- 使用
@WebServlet
、@WebFilter
、@WebListener
三个注解来替代web.xml文件中的Servlet、Filter、Listener的配置; - Servlet异步处理:当Servlet处理比较费时的问题时,这会让客户感觉到很卡。当使用异常处理时可以把已经处理好的内容先一步响应给客户端浏览器,然后使用另一个线程来完成费时的操作,也就是把内容一部分一部分的显示出来;
- 上传组件:不用再使用fileupload等第三方的上传组件,使用Servlet3.0的上传组件会更方便。
这篇文章我们介绍一下servlet3.0中对上传的支持。
二、回忆一下以前的上传
我们先回忆一下,以前的上传是怎么做的。
首先是对表单的要求:
- 表单的method必须是post,即
method="POST"
- 其次enctype属性为multipart/form-data,也就是
enctype="multipart/form-data"
- 而且一定要给出一个上传文件的表单项项
<input type="file" name="xxx"/>
然后是在servlet的使用上, request.getParameter()方法不能再使用,必须使用request.getInputStream()
来获取整个表单的数据。
而且我们还要使用 commons-fileupload
组件,创建工厂,创建解析器,使用解析器来解析request对象,得到List<FileStream>。
三、Servlet3.0 的上传
在servlet3.0中,我们使用上传的时候,表单的要求是不变的,还是需要上面说的那几项,可是我们在servlet中,就不必再使用commons-fileupload,而是使用Servlet3.0提供的上传组件接口。
接下来我们介绍一下上传的步骤:
1. 上传表单
为了演示,我们先创建一个上传的表单:
<form action="<c:url value='/AServlet'/>" method="post" enctype="multipart/form-data">
用户:<input type="text" name="username" /><br>
简历:<input type="file" name="resume" /><br>
<input type="submit" value="注册" />
</form>
表单中只有两个表单项,一个是用户名,username
。另一个是文件表单项,resume
。请求的URL为/AServlet
。
2. Servlet添加注解
要注意的一点是,默认Servlet是不支持使用上传组件:需要给Servlet添加一个注解: @MultipartConfig
也就是:
@MultipartConfig
public class AServlet extends HttpServlet {
...
...
}
3. 获取username
在servlet3.0中,request.getParameter()方法又可以重新使用了。
我们可以获取username字段的值。
也就是:
String username = request.getParameter("username");
4. 获取文件表单项
我们想要获得文件表单项的字段。应该使用getPart()
方法。
我们首先要使用request.getPart("字段名")
方法,得到对应的Part对象。
Part part = request.getPart("resume");
Part对象有几个重要的方法:
String getContentType()
:获取上传文件的MIME类型StringgetName()
:获取表单项的名称,不是文件名称String getHeader(String header)
:获取指定头的值long getSize()
:获取上传文件的大小InputStream getInputStream()
:获取上传文件的内容void write(String fileName)
:把上传文件保存到指定路径下
我们上面既然已经得到了Part对象,接下来利用它的方法,获取我们想要的信息就可以了。
例如:
// 获取上传文件的MIME类型
String contentType = part.getContentType();
System.out.println(contentType);
// 获取上传文件的字节数
long size = part.getSize();
System.out.println(size);
// 获取文件字段的名称
String name = part.getName();
System.out.println(name);
// 获取头信息,这个头中包含了上传文件的名称
String header = part.getHeader("Content-Disposition");
System.out.println(header);
// 保存文件
part.write("C:/XXX.jpg");
5. 上传文件名
有一点比较遗憾的是,他没有提供获取上传文件名的方法。这里呢,需要我们自己来完成对文件名的截取操作。
就从上面我们获取的Content-Disposition中截取出来即可。
// 截取文件名称
String header = part.getHeader("Content-Disposition");
int start = header.lastIndexOf("filename=\"") + 10;
int end = header.length() - 1;
String filename = header.substring(start, end);
System.out.println(filename);
END.