Servlet3.0之前上传文件通常借助commons-fileupload-xxx.jar和commons-io-xxx.jar两个jar包,其中相关的API较多,写起来非常不便。而在Servlet3.0时,改进了部分API,可以通过@MultipartConfig注解以及相关的方法比较方便的进行文件上传。
1.HttpServletRequest提供的方法
2.Part中常用的方法
3.表单enctype属性说明
在使用标签时,需要设置enctype="multipart/form-data",指定表单数据的编码方式。enctype属性值说明:
4.@MultipartConfig注解属性说明
属性 | 类型 | 是否必需 | 说明 |
---|---|---|---|
maxFileSize | long | 否 | |
maxRequestSize | long | 否 | |
fileSizeThreshold | int | 否 | |
location | String | 否 |
1.uploadUI.jsp
设置ectype属性为multipart/form-data才可上传文件
2.FileServlet.java
方式一:使用@MultipartConfig注解
(1).处理文件上传的Servlet使用@MultipartConfig注解修饰;该Servlet主要完成访问上传页面以及处理文件上传,通过HttpServletRequest提供的getPart(String name)或getParts()方法获取到上传的文件,再使用Part相关的API获取文件信息以及完成上传。
(2).通过该注解提供的属性:maxFileSize、maxRequestSize等可以对上传文件大小、请求大小进行控制
@WebServlet(name="fileServlet", urlPatterns="/file/*")
@MultipartConfig(
maxFileSize = 5*1024*1024
)
public class FileServlet extends HttpServlet {
private static final long serialVersionUID = 6956924658471003841L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String uri = request.getRequestURI();
String methodName = uri.substring(uri.lastIndexOf("/") + 1);
if (methodName.equals("uploadUI")) {// 上传页面
uploadUI(request, response);
} else if(methodName.equals("upload")){// 上传
upload(request, response);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
/**
* 文件上传页面
* @date 2017年5月1日
* @param request
* @param response
* @throws ServletException
* @throws IOException
* Description:
*/
public void uploadUI(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/jsp/file/uploadUI.jsp").forward(request, response);
}
/**
* 文件上传
* @date 2017年5月1日
* @param request
* @param response
* @throws ServletException
* @throws IOException
* Description:
*/
public void upload(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 普通参数
String name = request.getParameter("name");
System.out.println("name:" + name);
// 文件
Part part = request.getPart("upload");
this.uploadFile(part);
// 所有部件
// Collection parts = request.getParts();
// if(parts != null && parts.size() > 0){
// for(Part part : parts){
// this.uploadFile(part);
// }
// }
}
/**
* 上传文件
* @date 2017年5月2日
* @param part
* Description:
*/
private void uploadFile(Part part) {
try {
if (part != null) {
String submittedFileName = part.getSubmittedFileName();// 原文件名称,Servlet3.1提供
if (submittedFileName != null && part.getSize() > 0) {
// 获取上传文件信息
System.out.println("文件类型:" + part.getContentType());// MIME类型
System.out.println("文件大小:" + part.getSize());// 文件大小 字节
System.out.println("SubmittedFileName:" + part.getSubmittedFileName());
System.out.println("Name:" + part.getName());
// 获取文件上传域信息
Collection headerNames = part.getHeaderNames();
for (String headName : headerNames) {
System.out.println("headName:" + headName + " --- value:" + part.getHeader(headName));
}
// 保存至服务器
String basePath = this.getServletContext().getRealPath("/");
String path = basePath + "/uploads/file/" + part.getSubmittedFileName();
part.write(path);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
方式二:web.xml方式配置
使用web.xml方式配置时,需要在
fileServlet
cn.edu.njit.servlet.FileServlet
fileServlet
/file/*
3.测试说明
(1).使用getPart(String name)方法
在使用request.getPart("upload")时,只会获取表单中所有标签name属性为"upload"中第一个出现的标签,可能是文件、普通元素,所以最好要先判断是否是文件。
(2).使用getParts()方法
使用该方法时,获取表单中所有标签,遍历返回的Collection
(1).对于要上传文件的Servlet,注解方式配置时,使用@MultipartConfig注解修饰;web.xml配置时,使用
(2).Collection
(3).对上传文件的控制可借助@MultipartConfig提供的属性,但提示不友好,直接报500错误,最好能捕获该异常给出相应的友好提示;也可在Servlet中通过Part提供的API对上传文件进行控制。
(4).在文件上传时,保存到服务器的文件一般不使用原来的文件名,为避免重复可使用java.util.UUID工具生成文件名;还可根据日期创建目录并保存文件,如当前日期为2017-5-4,则可保存为2017/5/4/aaabbbccc.txt。
demo代码:https://github.com/mytt-10566/servlet