Servlet3.0——文件上传

Servlet3.0文件上传

1.Sevlet3.0提供了一个新API来处理上传数据:

  • Annotation MultipartConfig:      A servlet can be annotated with this annotation in order to handlemultipart/form-data requests which contain file upload data. 
    通过这个注解标记一个Servlet 可以处理multipart/form-data请求包含的文件上传操作。
         annotation has the following options:
     
      • fileSizeThreshold: file’s size that is greater than this threshold will be directly written to disk, instead of saving in memory.
                                              如果上传的文件内容长度大于此值,将会写入磁盘而不保存在内存中。
      • location: directory where file will be stored via Part.write() method.
                           文件保存的本地路径
      • maxFileSize: maximum size for a single upload file.
                                 单次上传文件长度最大值,此值为字节
      • maxRequestSize:maximum size for a request.
                                        单次上传文件长度最大值,此值为字节

        所有size单位为字节,-1L表示不限制。1024*1024*10 = 10 MB

  • Interface Partrepresents a part in a multipart/form-data request. This interface defines some methods for working with upload data (to name a few):
      • getInputStream(): returns an InputStream object which can be used to read content of the part.
                                           获取上传文件的文件流
      • getSize(): returns the size of upload data, in bytes.
                             文件大小
      • write(String filename): this is the convenience method to save upload data to file on disk. The file is created relative to the location specified in the MultipartConfig annotation.
  •           New methods introduced in HttpServletRequest interface:
    • getParts(): returns a collection of Part objects
                  获取多个上传文件对象
    • getPart(String name): retrieves an individual Part object with a given name.
                                                               获取指定名name的上传文件对象。<input type="file" name="abc">

示例代码---服务端:

@WebServlet(urlPatterns = "/upload.html")
@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 2, maxFileSize = 1024 * 1024 * 10, maxRequestSize = 1024 * 1024 * 50)
public class UploadFileServlet extends HttpServlet {
    private static final long    serialVersionUID    = 1L;
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("UploadFileServlet doPost invoked!");
        for (Part part : req.getParts()) {
            String fileName = extractFileName(part);
            part.write("D://xxx_"+fileName);
            
            /*
             * System.out.println("fileName=" + fileName); InputStream is =
             * null; OutputStream os = null; try { is = part.getInputStream();
             * os = new FileOutputStream(new File("D://xxx_" + fileName));
             * byte[] buf = new byte[1024]; int len = 0; while ((len =
             * is.read(buf)) != -1) { os.write(buf, 0, len); } } catch
             * (Exception e) { } finally { if (is != null) { os.close();
             * is.close(); } }
             */
        }
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().println("上传文件成功!");
        resp.getWriter().close();
    }
    /**
     * Extracts file name from HTTP header content-disposition
     */
    private String extractFileName(Part part) {
        String contentDisp = part.getHeader("content-disposition");
        String[] items = contentDisp.split(";");
        for (String s : items) {
            if (s.trim().startsWith("filename")) {
                return s.substring(s.indexOf("=") + 2, s.length() - 1);
            }
        }
        return "";
    }
}  
客户端:此处使用Jsoup代码的方式上传文件,而不是通过浏览器。不熟悉Jsoup的可以参数我另一篇博文“ HttpClient/Jsoup 请求
public static void main(String[] args) {
		InputStream is = null;
		try {
			String url = "http://localhost:8080/part1/upload.html";
			is = new FileInputStream(new File("D://abc.txt"));
			Response response = Jsoup.connect(url).data("gdr", "abcc.txt", is).method(Method.POST).execute();
			System.out.println(response.body());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
 
输出:
上传文件成功!  

注:该代码在Eclipse-Jetty插件中运行,一直没有将文件写入D://下。但在Tomcat中运行,一切正常。

造成这种现象很容易理解,Servlet为接口规范,其实现为各Web容器。

因此建议在保存文件时为了保证在各种Web容器中运行都有一至结果,建议通过Part接口获取文件输入流,自己实现文件保存功能。如示例中的注释。

猜你喜欢

转载自yeyusir.iteye.com/blog/2304384