文件上传与下载学习总结

  1. 文件上传对表单要求:
  2. 表单中的请求提交方式必须是POST
  3. 表单中应指定所提交的请求为multipart请求,通过在<form/>标签中添加enctype属性,其值为multipart/form-data
  4. 表单中要有file表单元素,查看multipart请求可以通过火狐浏览器的开发者工具中的参数去查看
  5. 文件的upload例子如下:
<%@ page
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	<form action="${pageContext.request.contextPath }/registerServlet" method="POST" enctype="multipart/form-data">
		姓名: <input type="text" name="name"/><br> 
		年龄: <input type="text" name="age"/><br>
		 照片: <input type="file" name="photo"/><br>
		<input type="submit" value="注册" />
	</form>
</body>
</html>
package com.bjpowernode.servlets;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class RegisterServlet extends HttpServlet {
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/*
		 * ServletInputStream is = request.getInputStream(); PrintWriter out =
		 * response.getWriter(); int len=-1; byte[] buffer=new byte[1024];
		 * while((len=is.read(buffer))!=-1) { String str = new String(buffer,0,len);
		 * out.print(str); } is.close();
		 */
		// 判断请求是否为multipart请求
		if (!ServletFileUpload.isMultipartContent(request)) {
			throw new RuntimeException("当前请求不支持文件上传");
		}
		try {
			// 创建一个FileItem工厂
			DiskFileItemFactory factory = new DiskFileItemFactory();
			// 设置使用临时文件的边界值,大于该值,上传文件会先保存在临时文件中,否则,上传文件将直接写入到内存
			// 单位:字节 本例设置边界值为1M
			factory.setSizeThreshold(1024 * 1024 * 1);

			// 设置临时文件
			String temppath = this.getServletContext().getRealPath("/temp");
			File file = new File(temppath);
			factory.setRepository(file);
			// 创建文件上传核心组件
			ServletFileUpload upload = new ServletFileUpload(factory);
			// 设置每一个item的头部字符编码,其可以解决文件名的中文乱码问题
			upload.setHeaderEncoding("UTF-8");
			//设置单个上传文件的最大边界值为2M
			upload.setFileSizeMax(1024*1024*2);
			//设置一次上传所有文件的总和最大值为5M(对于上传多个文件时起作用)
			upload.setSizeMax(1024*1024*5);
			// 解析请求,获取到所有的item
			List<FileItem> items = upload.parseRequest(request);
			// 遍历items
			for (FileItem item : items) {
				if (item.isFormField()) {// 若item为普通表单项
					String fieldName = item.getFieldName();// 获取表单项名称
					String value = item.getString("UTF-8"); // 获取表单项的值
					System.out.println(fieldName + " = " + value);
				} else { // 若item为文件表单项
					String filename = item.getName();// 获取上传文件原始名称
					filename = System.currentTimeMillis() + filename;
					// 获取输入流,其中有上传文件的内容
					InputStream is = item.getInputStream();
					// 获取文件保存在服务器的路径
					String path = this.getServletContext().getRealPath("/images");
					//获取当前系统时间
					Calendar now = Calendar.getInstance();
					//获取年、月、日
					int year = now.get(Calendar.YEAR);
					int month = now.get(Calendar.MONTH)+1;
					int day = now.get(Calendar.DAY_OF_MONTH);
					
					path=path+"/"+year+"/"+month+"/"+day;
					File dirFile = new File(path);
					//若该目录不存在,则创建这个目录
					if(!dirFile.exists()) {
					dirFile.mkdirs();
					}
					// 创建目标文件,将来用于保存上传文件
					File descfile = new File(path, filename);
					// 创建文件输出流
					OutputStream os = new FileOutputStream(descfile);
					// 将输入流中的数据写入到输出流中
					int len = -1;
					byte[] buffer = new byte[1024];
					while ((len = is.read(buffer)) != -1) {
						os.write(buffer, 0, len);
					}
					os.close();
					is.close();

					// 删除临时文件
					item.delete();
				}

			}
		} catch (FileUploadException e) {
			e.printStackTrace();
		}
	}

}

文件下载可以直接通过超链接去下载,但是浏览器能解析的文件会直接显示,解析不了才会以附件的形式出现,所以是由浏览器决定的,因此我们不建议用这种方式,应该用Servlet去爬下来服务器上的数据,也就是输出流读取输入流,应当再注意一下中文乱码问题,例子如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	<a href="${pageContext.request.contextPath}/downloadServlet">帅</a>
</body>
</html>
package com.bjpowernode.servlets;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DownloadServlet extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		String filename="帅气.jpg";
		//打散
		byte[] bytes = filename.getBytes("UTF-8");
		//组装
		filename=new String(bytes,"ISO8859-1");
		
		//修改响应的头部属性content-disposition为attachment
		response.setHeader("content-disposition", "attachment;filename="+filename);
		//获取连接服务端资源文件的输入流
		InputStream is = this.getServletContext().getResourceAsStream("/resources/aaa.jpg");
		//获取输出流
		ServletOutputStream os = response.getOutputStream();
		// 将输入流中的数据写入到输出流中
		int len = -1;
		byte[] buffer = new byte[1024];
		while ((len = is.read(buffer)) != -1) {
			os.write(buffer, 0, len);
		}
		os.close();
		is.close();

	}

}

 

posted @ 2019-10-06 11:24  小帅学java  阅读(21)  评论(0)    收藏  举报