Servlet3.0 新增了对文件上传请求解析的支持,javax.servlet.http.HttpServletRequest#getParts,使用request.getParts();即可获取文件上传包解析后的结果,从此不再需要使用第三方jar来处理文件上传请求了。

2.1 JSP multipart-config

JSP使用request.getParts();必须配置multipart-config,否则请求时会报错:Unable to process parts as no multi-part configuration has been provided(由于没有提供multi-part配置,无法处理parts)。
在web.xml中添加如下配置:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0"
  3. xmlns="http://java.sun.com/xml/ns/javaee"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  5. <servlet>
  6. <servlet-name>file-upload-parts.jsp</servlet-name>
  7. <jsp-file>/modules/servlet/fileupload/file-upload-parts.jsp</jsp-file>
  8. <multipart-config>
  9. <max-file-size>1000000</max-file-size>
  10. <max-request-size>1000000</max-request-size>
  11. <file-size-threshold>1000000</file-size-threshold>
  12. </multipart-config>
  13. </servlet>
  14. <servlet-mapping>
  15. <servlet-name>file-upload-parts.jsp</servlet-name>
  16. <url-pattern>/modules/servlet/fileupload/file-upload-parts.jsp</url-pattern>
  17. </servlet-mapping>
  18. </web-app>

示例 - file-upload-parts.jsp

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <%@ page import="org.apache.commons.io.IOUtils" %>
  3. <%@ page import="java.util.Collection" %>
  4. <%@ page import="java.io.File" %>
  5. <%
  6. String contentType = request.getContentType();
  7. // 检测是否是multipart请求
  8. if (contentType != null && contentType.startsWith("multipart/")) {
  9. String dir = request.getSession().getServletContext().getRealPath("/uploads/");
  10. File uploadDir = new File(dir);
  11. if (!uploadDir.exists()) {
  12. uploadDir.mkdir();
  13. }
  14. Collection<Part> parts = request.getParts();
  15. for (Part part : parts) {
  16. String fileName = part.getSubmittedFileName();
  17. if (fileName != null) {
  18. File uploadFile = new File(uploadDir, fileName);
  19. out.println(part.getName() + ": " + uploadFile.getAbsolutePath() + "<br/>");
  20. } else {
  21. out.println(part.getName() + ": " + IOUtils.toString(part.getInputStream()) + "<br/>");
  22. }
  23. }
  24. } else {
  25. %>
  26. <!DOCTYPE html>
  27. <html lang="zh">
  28. <head>
  29. <meta charset="UTF-8">
  30. <title>File upload</title>
  31. </head>
  32. <body>
  33. <form action="" enctype="multipart/form-data" method="post">
  34. <p>
  35. 用户名: <input name="username" type="text"/>
  36. 文件: <input id="file" name="file" type="file"/>
  37. </p>
  38. <input name="submit" type="submit" value="Submit"/>
  39. </form>
  40. </body>
  41. </html>
  42. <%
  43. }
  44. %>

访问示例中的文件上传地址:http://localhost:8000/modules/servlet/fileupload/file-upload-parts.jsp
3. 2. Servlet 3.0 内置文件上传解析 - 图1
文件上传成功:
3. 2. Servlet 3.0 内置文件上传解析 - 图2

2.2 Servlet @MultipartConfig

Servlet3.0 需要配置@MultipartConfig注解才能支持multipart解析。
示例 - FileUploadServlet代码:

  1. import org.apache.commons.io.FileUtils;
  2. import org.apache.commons.io.IOUtils;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.MultipartConfig;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import javax.servlet.http.Part;
  10. import java.io.File;
  11. import java.io.IOException;
  12. import java.io.PrintWriter;
  13. import java.util.Collection;
  14. @MultipartConfig
  15. @WebServlet(urlPatterns = "/FileUploadServlet")
  16. public class FileUploadServlet extends HttpServlet {
  17. @Override
  18. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  19. PrintWriter out = resp.getWriter();
  20. out.println("<!DOCTYPE html>\n" +
  21. "<html lang=\"zh\">\n" +
  22. "<head>\n" +
  23. " <meta charset=\"UTF-8\">\n" +
  24. " <title>File upload</title>\n" +
  25. "</head>\n" +
  26. "<body>\n" +
  27. "<form action=\"\" enctype=\"multipart/form-data\" method=\"post\">\n" +
  28. " <p>\n" +
  29. " 用户名: <input name=\"username\" type=\"text\"/>\n" +
  30. " 文件: <input id=\"file\" name=\"file\" type=\"file\"/>\n" +
  31. " </p>\n" +
  32. " <input name=\"submit\" type=\"submit\" value=\"Submit\"/>\n" +
  33. "</form>\n" +
  34. "</body>\n" +
  35. "</html>");
  36. out.flush();
  37. out.close();
  38. }
  39. @Override
  40. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  41. PrintWriter out = response.getWriter();
  42. String contentType = request.getContentType();
  43. // 检测是否是multipart请求
  44. if (contentType != null && contentType.startsWith("multipart/")) {
  45. String dir = request.getSession().getServletContext().getRealPath("/uploads/");
  46. File uploadDir = new File(dir);
  47. if (!uploadDir.exists()) {
  48. uploadDir.mkdir();
  49. }
  50. Collection<Part> parts = request.getParts();
  51. for (Part part : parts) {
  52. String fileName = part.getSubmittedFileName();
  53. if (fileName != null) {
  54. File uploadFile = new File(uploadDir, fileName);
  55. out.println(part.getName() + ": " + uploadFile.getAbsolutePath());
  56. FileUtils.write(uploadFile, IOUtils.toString(part.getInputStream(), "UTF-8"));
  57. } else {
  58. out.println(part.getName() + ": " + IOUtils.toString(part.getInputStream()));
  59. }
  60. }
  61. }
  62. out.flush();
  63. out.close();
  64. }
  65. }

访问示例中的文件上传地址:http://localhost:8000/FileUploadServlet
3. 2. Servlet 3.0 内置文件上传解析 - 图3
文件上传成功:
3. 2. Servlet 3.0 内置文件上传解析 - 图4