使用Servlet3.0注解完成文件上传功能

关于注解的使用说明可以先看这篇文章详情

本文主要介绍@MultipartConfig的使用,@MultipartConfig没有任何属性,如果需要支持文件上传,那么只需要在Servlet类上添加该注解声明即可.

@MultipartConfig声明后的Servlet,既可以实现单个文件上传,也可以实现多个文件上传,同时还支持获取表单中的其他指字段.

Servlet3.0将multipart/form-data的POST请求封装成Part对象,通过Part对象完成上传文件的行操作,但是它没有提供直接获取文件名的方法,需要通过Part对象从请求头中解析出来,不同浏览器获取的请求头格式还不一样,主要分以下2种:

  • 火狐和google浏览器下:form-data;name="file";filename="test.png"
  • IE浏览器下:form-data;name="file";filename="E:\test.png"

其中test.png是上传的文件.

通过request对象可以获取所有的Part对象集合,也可以通过表单file控件(<input type="file" name="file">)的名字直接获取单个Part对象.

最后,通过Part对象的void write(String fileName)方法,传入一个保存文件的绝对路径,即可保存上传的文件.或者通过Part对象的getInputStream()方法获取输入流来完成文件的保存操作.

编写上传页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>@MultipartConfig文件上传</title>
</head>
<body>
	<!-- 文件上传时必须要设置表单的enctype="multipart/form-data"-->
	<form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">
		用户名: <input type="text" name="username"> <br> 
		上传文件: <input type="file" name="file"> <br> 
		<input type="submit" value="上传">
	</form>
	
	
	<!-- 文件上传时必须要设置表单的enctype="multipart/form-data"-->
    <form action="${pageContext.request.contextPath}/upload"  method="post" enctype="multipart/form-data">
        用户名: <input type="text" name="username"> <br>         
        上传文件:<input type="file" name="file1"><br>
        上传文件:<input type="file" name="file2"><br>
        <input type="submit" value="上传">
     </form>
     
</body>
</html>

编写处理文件上传的Servlet

package blog.csdn.net.upload;

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

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 = { "/upload" })
// 使用注解@MultipartConfig将一个Servlet标识为支持文件上传
@MultipartConfig
public class UploadServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("utf-8");
		resp.setContentType("text/html;charset=utf-8");

		// 获取普通表单字段
		String username = req.getParameter("username");
		System.out.println(username);

		// 定义文件保存的路径
		String path = req.getServletContext().getRealPath("/upload");

		// 获取上传的文件集合
		Collection<Part> parts = req.getParts();
		if (parts.size() == 1) {
			// 说明上传的文件只有一个
			Part part = req.getPart("file");// 通过控件名字获取part
			saveUploadFile(path, part);
		} else {
			// 多文件上传
			for (Part part : parts) {
				saveUploadFile(path, part);
			}
		}
		PrintWriter pw = resp.getWriter();
		pw.println("上传成功");
		pw.close();
	}


      /**
	 * 保存上传的文件
	 * @param dir
	 * @param part
	 * @throws IOException
	 */
	public void saveUploadFile(String dir, Part part) throws IOException {
		//判断控件的name属性的值是否是file(注意必须和表单里面的文件控件name属性一致),如果不是不作处理
		//避免普通控件造成多次该文件的io流操作.
		if (null != part && part.getName().equals("file")) {
			// 获取请文件上传的请求头
			String header = part.getHeader("content-disposition");
			// 获取文件名
			String fileName = getFileNameByHeader(header);
			fileName = getUUIDName(fileName);
			// 上传文件保存的文件夹不存在的话需要先创建
			File saveFile = new File(dir, fileName);
			if (!saveFile.getParentFile().exists()) {
				saveFile.getParentFile().mkdirs();
			}
			// 保存文件
			part.write(saveFile.getAbsolutePath());
			//也可以使用part.getInputStream()获取输入流来完成文件保存操作.
			
		}
		
	}

	/**
	 * 根据请求头解析出文件名 请求头的格式:
	 * 火狐和google浏览器下:form-data;name="file";filename="test.png"
	 * IE浏览器下:form-data;name="file";filename="E:\test.png"
	 * 
	 * @param header请求头
	 * @return 文件名
	 */
	private String getFileNameByHeader(String header) {

		String[] tempArr1 = header.split(";");
		if(tempArr1.length==3) {
			String[] tempArr2 = tempArr1[2].split("=");
			if(tempArr2.length==2) {
				String filename = tempArr2[1];
				return filename.substring(filename.lastIndexOf("\\")+1).replaceAll("\"", "");
			}
		}
		return System.currentTimeMillis()+"";
	}

	
	/**
	 * 获取保存文件的唯一名称
	 * @param realName
	 * @return
	 */
	public static String getUUIDName(String realName){
		//获取后缀名
		int index = realName.lastIndexOf(".");
		if(index==-1){
			return UUID.randomUUID().toString().replace("-", "").toUpperCase();
		}else{
			return UUID.randomUUID().toString().replace("-", "").toUpperCase()+realName.substring(index);
		}
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		this.doGet(req, resp);
	}
}

猜你喜欢

转载自blog.csdn.net/mChenys/article/details/81284100