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

此前,对于处理上传文件的操作一直是让开发者头疼的问题,因为 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);
	}
}

 

转载于:https://my.oschina.net/u/3421709/blog/1305715

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值