jsp + servlet 文件上传

1. 进行文件上传时, 表单需要做的准备:

1). 请求方式为 POST: <form action="uploadServlet" method="post" ... >
2). 使用 file 的表单域: <input type="file" name="file"/>
3). 使用 multipart/form-data 的请求编码方式: <form action="uploadServlet" method="post" enctype="multipart/form-data">


jsp

<%@ 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>Insert title here</title>
</head>
<body>
	<form action="${pageContext.request.contextPath }/uploadServlet" method="post"
		enctype="multipart/form-data">
		File:<input type="file" name="file" /> <br> 
		desc:<input type="text" name="desc"> <br> 
		<input type="submit">
	</form>
</body>
</html>

4). 关于 enctype:
> application/x-www-form-urlencoded:表单 enctype 属性的默认值。这种编码方案使用有限的字符集,当使用了非字母和数字时,
必须用”%HH”代替(H 代表十六进制数字)。对于大容量的二进制数据或包含非 ASCII 字符的文本来说,这种编码不能满足要求。

> multipart/form-data:form 设定了enctype=“multipart/form-data”属性后,表示表单以二进制传输数据 


2.使用commons-fileupload组件上传文件

lib:

commons-fileupload-1.2.1.jar
commons-io-2.0.jar

基本思想: 

> commons-fileupload 可以解析请求, 得到一个 FileItem 对象组成的 List
> commons-fileupload 把所有的请求信息都解析为 FileItem 对象, 无论是一个一般的文本域还是一个文件域. 
> 可以调用 FileItem 的 isFormField() 方法来判断是一个 表单域 或不是表单域(则是一个文件域)
> 再来进一步获取信息

public class uploadServlet extends HttpServlet {

	private static final long serialVersionUID = -7199179697800254436L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		this.doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		//1、创建一个DiskFileItemFactory工厂
		DiskFileItemFactory factory = new DiskFileItemFactory();
		FileCleaningTracker fileCleaningTracker = FileCleanerCleanup.getFileCleaningTracker(getServletContext());
		factory.setFileCleaningTracker(fileCleaningTracker);
		
		// 设置内存缓冲区,超过后写入临时文件
		factory.setSizeThreshold(1024 * 1024 * 5);
		File tmpDirectory = new File("d:\\tempDirectory");
		factory.setRepository(tmpDirectory);

		//2、创建一个文件上传解析器
		ServletFileUpload upload = new ServletFileUpload(factory);

		//设置上传的单个文件最大字节数 
		upload.setSizeMax(1024 * 1024 * 5);

		try {
			List<FileItem> parseRequest = upload.parseRequest(req);
			for (FileItem fileItem : parseRequest) {
				// 2.遍历items:若是一般表单域,打印信息
				if (fileItem.isFormField()) {
					String name = fileItem.getFieldName();
					String value = fileItem.getString();
					System.out.println(name + ":" + value);
				}else{
					//若是文件域则把文件保存到 d:\\files 目录下.
					String fieldName = fileItem.getFieldName();
					String name = fileItem.getName();
					String contentType = fileItem.getContentType();
					long size = fileItem.getSize();
					
					System.out.println(fieldName);
					System.out.println(name);
					System.out.println(contentType);
					System.out.println(size);
					
					InputStream inputStream = fileItem.getInputStream();
					byte[] buffer  = new byte[1024];
					int len = 0;
					fieldName ="d:\\files\\"+name;
					System.out.println(fieldName);
					FileOutputStream outputStream = new FileOutputStream(fieldName);
					
					
					while((len=inputStream.read(buffer))!=-1){
						outputStream.write(buffer, 0, len);
					}
					outputStream.close();
					inputStream.close();
					
				}
			}

		} catch (FileUploadException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

//		ServletInputStream inputStream = req.getInputStream();
//		Reader reader = new InputStreamReader(inputStream);
//		BufferedReader bufferedReader = new BufferedReader(reader);
//		String str = null;
//		while ((str = bufferedReader.readLine()) != null) {
//			System.out.println(str);
//		}
	}

}

多文件上传

jsp

<%@ 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>Insert title here</title>
<script type="text/javascript" src="${pageContext.request.contextPath }/scripts/jquery-1.7.2.js"></script>
<script type="text/javascript">
	
	$(function(){
		
		var i = 2;
		
		$("#addFile").click(function(){
			$(this).parent().parent().before("<tr class='file'><td>File" 
					+ i + ":</td><td><input type='file' name='file" 
					+ i + "'/></td></tr>"
					+ "<tr class='desc'><td>Desc" 
					+ i + ":</td><td><input type='text' name='desc" 
					+ i + "'/><button id='delete" 
					+ i + "'>删除</button></td></tr>");
			i++;
			
			//获取新添加的删除按钮
			$("#delete" + (i-1)).click(function(){
				var $tr = $(this).parent().parent();
				$tr.prev("tr").remove();
				$tr.remove();
				
				//对 i 重写排序
				$(".file").each(function(index){
					var n = index + 1;
					
					$(this).find("td:first").text("File" + n);
					$(this).find("td:last input").attr("name", "file" + n);
				});
				
				$(".desc").each(function(index){
					var n = index + 1;
					
					$(this).find("td:first").text("Desc" + n);
					$(this).find("td:last input").attr("name", "desc" + n);
				});
				
				i = i - 1;
			});
			
			return false;
		});
		
	});
	
</script>

</head>
<body>

	<font color="red">${msg }</font>
	<br><br>

	
	<form action="${pageContext.request.contextPath }/app/FileUploadServlet" method="post" enctype="multipart/form-data">
		
		<table>
			<tr class="file">
				<td>File1:</td>
				<td><input type="file" name="file1"/></td>
			</tr>
			<tr class="desc">
				<td>Desc1:</td>
				<td><input type="text" name="desc1"/></td>
			</tr>
			
			<tr>
				<td><input type="submit" id="submit" value="提交"/></td>
				<td><button id="addFile">新增一个附件</button></td>
			</tr>
		</table>
		
	</form>

</body>
</html>

upload.properties

exts=pptx,docx,doc,zip
file.MaxSize=102400
total.file.max.size=512000

FileUploadAppProperties

public class FileUploadAppProperties {
	private Map<String, String> properties = new HashMap<>();

	private FileUploadAppProperties() {
	}

	private static FileUploadAppProperties instance = new FileUploadAppProperties();

	public static FileUploadAppProperties getInstance() {
		return instance;
	}

	public void addProperties(String propertyName, String propertyValue) {
		properties.put(propertyName, propertyValue);
	}

	public String getProperties(String propertyName) {
		return properties.get(propertyName);
	}

}


监听器加载配置文件

FileUploadAppLitener

@WebListener
public class FileUploadAppLitener implements ServletContextListener {


	@Override
	public void contextInitialized(ServletContextEvent arg0) {
		InputStream in = getClass().getClassLoader().getResourceAsStream("/upload.properties");
		Properties properties = new Properties();


		try {
			properties.load(in);
			for (Map.Entry<Object, Object> pro : properties.entrySet()) {
				String propertName = (String) pro.getKey();
				String propertValue = (String) pro.getValue();
				FileUploadAppProperties.getInstance().addProperties(propertName, propertValue);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	@Override
	public void contextDestroyed(ServletContextEvent arg0) {
		// TODO Auto-generated method stub
	}
}


FileUploadBean

public class FileUploadBean {
	private Integer id;
	// 文件名
	private String fileName;
	// 文件路径
	private String filePath;
	// 文件描述
	private String fileDesc;


	public FileUploadBean() {
	}


	public FileUploadBean(String fileName, String filePath, String fileDesc) {
		super();
		this.fileName = fileName;
		this.filePath = filePath;
		this.fileDesc = fileDesc;
	}
        setter ...getter ..
}



FileUploadServlet

@WebServlet("/app/FileUploadServlet")
public class FileUploadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private static final String FILE_PATH = "/WEB-INF/files";

	private static final String TEMP_DIR = "d:\\tempDirectory";

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		String path;

		try {
			ServletFileUpload upload = getServletUpload();

			String fileSaveDir = getServletContext().getRealPath(FILE_PATH);
			File file = new File(fileSaveDir);
			if (!file.exists()) {
				file.mkdirs();
			}

			// 把需要上传的FileItem 都放入到该Map中
			// 键:文件的待存放的路径,值:对应的FileItem对象
			Map<String, FileItem> uploadFiles = new HashMap<>();
			// 解析请求,得到FileItem 的集合
			List<FileItem> items = upload.parseRequest(request);
			// 1.构建FileUploadBean 的集合,同时填充uploadFiles
			List<FileUploadBean> beans = buildFileUploads(items, uploadFiles);
			// 2.校验扩展名
			vaidateExtName(beans);
			// 3.校验文件的大小:在解析时,已经检验了,我们只需通过异常得到结果
			// 4.进行文件的上传操作
			upload(uploadFiles);
			// 5.把上传的信息保存到数据库
			saveBean(beans);
			
			//6. 删除临时文件夹的临时文件
			FileUtils.delAllFile(TEMP_DIR);
			
			path = "/app/success.jsp";
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			String msg = e.getMessage();
			
			path = "/app/upload.jsp";
			request.setAttribute("msg", msg);

		}
		request.getRequestDispatcher(path).forward(request, response);

	}

	private void saveBean(List<FileUploadBean> beans) {
		// TODO Auto-generated method stub

	}

	private void upload(Map<String, FileItem> uploadFiles) throws IOException {
		for (Map.Entry<String, FileItem> uploadFile : uploadFiles.entrySet()) {
			String filePath = uploadFile.getKey();
			FileItem fileItem = uploadFile.getValue();
			System.out.println(filePath);
			upload(filePath, fileItem.getInputStream());
		}

	}

	private void upload(String filePath, InputStream in) throws IOException {
		FileOutputStream outputStream = new FileOutputStream(filePath);
		byte[] buffer = new byte[1024];
		int len = 0;

		while ((len = in.read(buffer)) != -1) {
			outputStream.write(buffer, 0, len);
		}
		outputStream.close();
		in.close();

	}

	/**
	 * 校验扩展名是否合法
	 * 
	 * @param beans
	 */
	private void vaidateExtName(List<FileUploadBean> beans) {
		String exts = FileUploadAppProperties.getInstance().getProperties("exts");
		List<String> extList = Arrays.asList(exts.split(","));
		for (FileUploadBean bean : beans) {
			String fileName = bean.getFileName();
			String extName = fileName.substring(fileName.lastIndexOf(".") + 1);
			if (!extList.contains(extName)) {
				throw new InvalidExtNameException(fileName + "文件的扩展名不合法");
			}
		}

	}

	private List<FileUploadBean> buildFileUploads(List<FileItem> items, Map<String, FileItem> uploadFiles)
			throws UnsupportedEncodingException {
		List<FileUploadBean> beans = new ArrayList<>();
		// 1.遍历FileItem的集合,先得到的desc的Map<String,String>,其中键:fileName(desc1,desc2...)
		// 值表单域对应字段的值
		Map<String, String> descs = new HashMap<>();
		for (FileItem item : items) {
			if (item.isFormField()) {
				descs.put(item.getFieldName(), item.getString());
			}
		}
		// 2/再遍历FileItem集合,得到文件域的FileItem对象
		// 每个得到一个FileItem对象都创建一个FileUploadBean 对象
		// 得到 fileName,构建filePath,从1的Map中得到当前FileItem对应的那个desc
		// 使用fileName后面的数字匹配
		for (FileItem item : items) {
			if (!item.isFormField()) {
				String fieldName = item.getFieldName();
				String index = fieldName.substring(fieldName.length() - 1);
				// 上传文件名
				String fileName = item.getName();

				System.out.println(fileName);
				String desc = descs.get("desc" + index);
				String filePath = getFilePath(fileName);
				FileUploadBean fileUploadBean = new FileUploadBean(fileName, filePath, desc);
				beans.add(fileUploadBean);

				uploadFiles.put(filePath, item);
			}
		}
		return beans;
	}

	private String getFilePath(String fileName) {
		String extName = fileName.substring(fileName.lastIndexOf("."));
		// 生成随机数,防止filePath相同
		Random random = new Random();
		int randomNumber = random.nextInt(10000);
		String filePath = getServletContext().getRealPath(FILE_PATH) + File.separator + System.currentTimeMillis()
				+ randomNumber + extName;
		return filePath;
	}

	private ServletFileUpload getServletUpload() {
		String exts = FileUploadAppProperties.getInstance().getProperties("exts");
		String maxSize = FileUploadAppProperties.getInstance().getProperties("file.MaxSize");
		String total = FileUploadAppProperties.getInstance().getProperties("total.file.max.size");

		System.out.println(exts);

		DiskFileItemFactory factory = new DiskFileItemFactory();

		// 设置内存缓冲区,超过后写入临时文件
		factory.setSizeThreshold(1024 * 5);
		File tmpDirectory = new File(TEMP_DIR);
		factory.setRepository(tmpDirectory);

		// Create a new file upload handler
		ServletFileUpload upload = new ServletFileUpload(factory);

		// 解决路径或者文件名为乱码的问题
		upload.setHeaderEncoding("UTF-8");

		// Set overall request size constraint
		upload.setSizeMax(Long.parseLong(total));//设置整个表单的上传文件最大字节数 
		upload.setFileSizeMax(Long.parseLong(maxSize));//设置上传的单个文件最大字节数 
		return upload;
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

public class FileUtils {

	/**
	 * 删除文件夹
	 * @param folderPath:  文件夹完整绝对路径
	 */
	public static void delFolder(String folderPath) {
		try {
			// 删除完里面所有内容
			delAllFile(folderPath);
			String filePath = folderPath;
			filePath = filePath.toString();
			java.io.File myFilePath = new java.io.File(filePath);
			// 删除空文件夹
			myFilePath.delete();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 删除指定文件夹下所有文件
	 * @param path: 文件夹完整绝对路径
	 * @return
	 */
	public static boolean delAllFile(String path) {
		boolean flag = false;
		File file = new File(path);
		if (!file.exists()) {
			return flag;
		}
		if (!file.isDirectory()) {
			return flag;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(File.separator)) {
				temp = new File(path + tempList[i]);
			} else {
				temp = new File(path + File.separator + tempList[i]);
			}
			if (temp.isFile()) {
				temp.delete();
			}
			if (temp.isDirectory()) {
				// 先删除文件夹里面的文件
				delAllFile(path + "/" + tempList[i]);
				// 再删除空文件夹
				delFolder(path + "/" + tempList[i]);
				flag = true;
			}
		}
		
		return flag;
	}

}


http://www.cnblogs.com/lj821022/p/5720605.html


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值