您的位置:首页 > 理论基础 > 计算机网络

Servlet3.0 新特性——HttpServletRequest 对文件上传的支持

2017-07-10 00:00 645 查看
此前,对于处理上传文件的操作一直是让开发者头疼的问题,因为 Servlet 本身没有对此提供直接的支持,需要使用第三方框架( commons-io + commons-fileupload )来实现,而且使用起来也不够简单。如今这都成为了历史,Servlet 3.0 已经提供了这个功能,而且使用也非常简单。为此,HttpServletRequest 提供了两个方法用于从请求中解析出上传的文件:

Part getPart(String name)

Collection<Part> getParts()

前者用于获取请求中给定 name 的文件,后者用于获取所有的文件。每一个文件用一个 javax.servlet.http.Part 对象来表示。该接口提供了处理文件的简易方法,比如 write()、delete() 等。至此,结合 HttpServletRequest 和 Part 来保存上传的文件变得非常简单,如下所示:

1
2
3
Part photo = request.getPart("photo");

photo.write("/tmp/photo.jpg");

// 可以将两行代码简化为 request.getPart("photo").write("/tmp/photo.jpg") 一行。

另外,开发者可以配合前面提到的 @MultipartConfig 注解来对上传操作进行一些自定义的配置,比如限制上传文件的大小,以及保存文件的路径等。

需要注意的是,如果请求的 MIME 类型不是 multipart/form-data,则不能使用上面的两个方法,否则将抛异常。

具体配置如下:

准备上传页面 upload.jsp

上传页面有两点需要注意

1. form 的method必须是post的,get不能上传文件。 还需要加上enctype="multipart/form-data" 表示提交的数据是二进制文件

<form action="uploadPhoto" method="post" enctype="multipart/form-data">

2. 需要提供type="file" 的字段进行上传

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
<title>Servlet3.0实现文件上传</title>
</head>

<body>
<fieldset>
<legend> 上传单个文件 </legend>
<!-- 文件上传时必须要设置表单的enctype="multipart/form-data"-->
<form action="${pageContext.request.contextPath}/UploadServlet"
method="post" enctype="multipart/form-data">
上传文件: <input type="file" name="file"> <br> <input
type="submit" value="上传">
</form>
</fieldset>
<hr />
<fieldset>
<legend> 上传多个文件 </legend>
<!-- 文件上传时必须要设置表单的enctype="multipart/form-data"-->
<form action="${pageContext.request.contextPath}/UploadServlet"
method="post" enctype="multipart/form-data">
姓名:<input name="username" type="text"><br>
上传文件: <input type="file" name="file1"> <br>
上传文件: <input type="file" name="file2"><br>
上传文件: <input type="file" name="file3">
性别:<input name="sex" type="text"><br>
<br> <input type="submit" value="上传">
</form>
</fieldset>

<%=application.getRealPath("/WEB-INF/uploadFile")%>
</body>
</html>


准备 UploadPhotoServlet

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

//使用@WebServlet配置UploadServlet的访问路径
@WebServlet(name = "UploadServlet", urlPatterns = "/UploadServlet")
// 使用注解@MultipartConfig将一个Servlet标识为支持文件上传
@MultipartConfig
// 标识Servlet支持文件上传
public class UploadServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

// System.out.println(request.getParameter("username"));

// 存储路径
String savePath = request.getServletContext().getRealPath(
"/WEB-INF/uploadFile");

File f = new File(savePath);
if (!f.exists()) {
f.mkdirs();
}

// 获取上传的文件集合,重中之重,切记!
Collection<Part> parts = request.getParts();
// 上传单个文件

String username;

// 一次性上传多个文件
for (Part part : parts) {// 循环处理上传的文件
if (part.getHeader("content-disposition").indexOf("filename") == -1) {
username = request.getParameter("username");
} else {
// 获取请求头,请求头的格式:form-data; name="file";
// filename="snmp4j--api.zip"
String header = part.getHeader("content-disposition");
// 获取文件名
String fileName = getFileName(header);
// 把文件写到指定路径
part.write(savePath + File.separator + fileName);
}
}

// 处理业务逻辑
//username

PrintWriter out = response.getWriter();
out.println("上传成功");
out.flush();
out.close();
}

/**
* 根据请求头解析出文件名 请求头的格式:火狐和google浏览器下:form-data; name="file";
* filename="snmp4j--api.zip" IE浏览器下:form-data; name="file";
* filename="E:\snmp4j--api.zip"
*
* @param header
*            请求头
* @return 文件名
*/
public String getFileName(String header) {
/**
* String[] tempArr1 =
* header.split(";");代码执行完之后,在不同的浏览器下,tempArr1数组里面的内容稍有区别
* 火狐或者google浏览器下:
* tempArr1={form-data,name="file",filename="snmp4j--api.zip"}
* IE浏览器下:tempArr1={form-data,name="file",filename="E:\snmp4j--api.zip"}
*/
String[] tempArr1 = header.split(";");
/**
* 火狐或者google浏览器下:tempArr2={filename,"snmp4j--api.zip"}
* IE浏览器下:tempArr2={filename,"E:\snmp4j--api.zip"}
*/
String[] tempArr2 = tempArr1[2].split("=");
// 获取文件名,兼容各种浏览器的写法
String fileName = tempArr2[1].substring(
tempArr2[1].lastIndexOf("\\") + 1).replaceAll("\"", "");
return fileName;
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: