upload.java 手动处理文件上传
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*********文件上传组件: 手动处理文件上传************/
/*
* 如果要获取上传文件数据,需要对上面结果进行分析!
* 如果自己解析,比较麻烦!
* 通常,对于文件上传,我们使用别人写好的解析程序!
* 即使用别人写好的组件,这个组件就叫FileUpload组件!
* */
/*
*request.getQueryString(); //获取get:username=Tom&pwd=888
*request.getInputStrng(); //获取post:inputStream
*request.getParament("");
*/
//1.获取表单(post)数据
InputStream in = request.getInputStream();
//2.转换流
InputStreamReader inReader = new InputStreamReader(in);
//3.缓冲流
BufferedReader reader = new BufferedReader(inReader);
String str = null;
while((str=reader.readLine())!=null){
System.out.println(str);
/*
* -----------------------------41184676334
Content-Disposition: form-data; name="userName"
123
-----------------------------41184676334
Content-Disposition: form-data; name="file_img"; filename="123.txt"
Content-Type: text/plain
123456789
-----------------------------41184676334--
* */
}
reader.close();
inReader.close();
in.close();
}
upload.java 文件处理上传
/*
* FileUpload组件:文件上传组件!是apache提供的开源项目!
*
* item.getFieldName(); //获取上传表单元素名称
* item.getString(); //获取上传数据
* item.getString("UTF-8"); //获取上传数据,处理中文
* item.getContentType(); //获取上传文件类型(文件项)
* item.getName(); //获取文件名(文件项)
* item.getInputStream(); //获取文件流(文件项)
* item.write(file); //写文件
* item.delete(file); //删除临时文件
* */
private void upload(HttpServletRequest request, HttpServletResponse response) {
// TODO Auto-generated method stub
/*********文件上传组件: 处理文件上传************/
try {
//1.创建文件上传工厂类,把每一个请求表单项封装为一个个FileItem对象
FileItemFactory factory = new DiskFileItemFactory();
//2.创建文件上传核心对象,可以FileItem对象
//ServletFileUpload upload = new ServletFileUpload(factory);
ServletFileUpload upload = new ServletFileUpload();
upload.setFileItemFactory(factory);
upload.setFileSizeMax(30*1024*1024); //设置单个文件的最大值:30M
upload.setSizeMax(80*1024*1024); //设置总文件大小:80M
//upload.setHeaderEncoding("UTF-8"); //上传文件名的编码,相当于request.setContentType(..);
//3.判断当前表单是否为文件上传表单
if(upload.isMultipartContent(request)){
/*4.把请求数据转换为FileItem对象,再用集合封装
* 封装了普通表单项的值以及文件上传表单元素值
* */
List<FileItem> items = upload.parseRequest(request);
//5.遍历:得到每一个上传项
for(FileItem item : items){
//6.判断:是普通表单项,还是文件上传表项
if(item.isFormField()){
//普通表单
String fieldName = item.getFieldName();
String value = item.getString("UTF-8");
System.out.println("文本框名称:"+fieldName+"\n文本框值:"+value);
}
//上传文件(文本流)----》上传到upload目录下
else {
//文件上传表单
String fieldName = item.getFieldName();
String contentType = item.getContentType();
String fileName = item.getName();
InputStream in = item.getInputStream();
System.out.println("文本框名称:"+fieldName+"\n文件类型:"+contentType+"\n文件名:"+fileName+"\n文件流:"+in);
/*
* 7.文件名重名
* 对于不同用户123.txt文件,不希望覆盖
* 后台处理:给用户添加一个唯一标记
* */
//a.随机生成一个唯一标记
String id = UUID.randomUUID().toString();
//b.与文件名拼接
fileName = id + "#" + fileName;
/* 原先:fileName = 123.txt
* 现在:fileName = 22bcd484-35bd-432d-a46b-f8438c274ada#123.txt
*
* UUID.randomUUID().toString()是javaJDK提供的一个自动生成主键的方法。
* UUID(Universally Unique Identifier)全局唯一标识符,
* 是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的,
* 是由一个十六位的数字组成,表现出来的 形式。
* 由以下几部分的组合:当前日期和时间
* (UUID的第一个部分与时间有关,如果你在生成一个UUID之后,
* 过几秒又生成一个UUID,则第一个部分不 同,其余相同),
* 时钟序列,全局唯一的IEEE机器识别号
* (如果有网卡,从网卡获得,没有网卡以其他方式获得),
* UUID的唯一缺陷在于生成的结果串会比较长。
* */
//获取上传的目录路径
String basePath = getServletContext().getRealPath("/upload");
//创建文件对象
File file = new File(basePath,fileName);
item.write(file); //写文件
item.delete(); //删除临时文件
}
}
}else{
System.out.println("当前表单不是文件上传表单,处理失败!");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
实现上传下载完整案例
使用标签时,一定要在jsp文件头加入以下代码:
<%@taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core” %>
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>index</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<a href="${pageContext.request.contextPath }/upload.jsp">文件上传</a>
<a href="${pageContext.request.contextPath }/FileServlet?method=downList">文件下载</a>
</body>
</html>
upload.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>upload</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<!-- 指定表单类型为文件上传表单:enctype="multipart/form-data" -->
<!-- 提交方式为:post -->
<!-- 表单中,存在文件域元素 -->
<form action="${pageContext.request.contextPath }/FileServlet?method=upload" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="userName"><br>
文件:<input type="file" name="file_img"><br>
<input type="submit">
</form>
</body>
</html>
downlist.jsp 文件下载目录列表显示
<%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>下载列表</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
<table border="1" align="center">
<tr>
<th>序号</th>
<th>文件名</th>
<th>操作</th>
</tr>
<!--
items 用于接收集合对象,
var 定义对象接收从集合里遍历出的每一个元素。同时其会自动转型。
varStatus 表示当前集合的状态
${status.index} 输出行号,从0开始。
${status.count} 输出行号,从1开始。
${status.current} 当前这次迭代的(集合中的)项
${status.first} 判断当前项是否为集合中的第一项,返回值为true或false
${status.last} 判断当前项是否为集合中的最后一项,返回值为true或falsebegin、end、step分别表示:起始序号,结束序号,跳跃步伐。
如:<c:forEach begin='1' end='5' step='2' items='${list}' var='item'>表示:操作list集合汇中1~5条数据,不是逐条循环,而是按每2个取值。即操作集合中的第1、3、5条数据。
-->
<c:forEach var="en" items="${requestScope.fileNames}" varStatus="vs">
<tr>
<td>${vs.count }</td>
<td>${en.value }</td>
<td>
<!-- <a herf="pageContext.request.contextPath"/FileServlet?method=down&..>下载</a> -->
<!-- 构建一个地址 -->
<!-- <c:url var="url" value="/FileServlet" context="day23_web"></c:url> -->
<c:url var="url" value="/FileServlet">
<c:param name="method" value="down"></c:param>
<c:param name="fileName" value="${en.key }"></c:param>
</c:url>
<!-- 使用上面地址 -->
<a href="${url }">下载</a>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
FileServlet.java 处理上传下载文件
package servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
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.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
* 处理文件上传与下载
* @author Jie.Yuan
*
*/
public class FileServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取请求参数: 区分不同的操作类型
String method = request.getParameter("method");
if ("upload".equals(method)) {
// 上传
upload(request,response);
}
else if ("downList".equals(method)) {
// 进入下载列表
downList(request,response);
}
else if ("down".equals(method)) {
// 下载
down(request,response);
}
}
/**
* 1. 上传
*/
private void upload(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
// 1. 创建工厂对象
FileItemFactory factory = new DiskFileItemFactory();
// 2. 文件上传核心工具类
ServletFileUpload upload = new ServletFileUpload(factory);
// 设置大小限制参数
upload.setFileSizeMax(10*1024*1024); // 单个文件大小限制
upload.setSizeMax(50*1024*1024); // 总文件大小限制
upload.setHeaderEncoding("UTF-8"); // 对中文文件编码处理
// 判断
if (upload.isMultipartContent(request)) {
// 3. 把请求数据转换为list集合
List<FileItem> list = upload.parseRequest(request);
// 遍历
for (FileItem item : list){
// 判断:普通文本数据
if (item.isFormField()){
// 获取名称
String name = item.getFieldName();
// 获取值
String value = item.getString();
System.out.println(value);
}
// 文件表单项
else {
/******** 文件上传 ***********/
// a. 获取文件名称
String name = item.getName();
// ----处理上传文件名重名问题----
// a1. 先得到唯一标记
String id = UUID.randomUUID().toString();
// a2. 拼接文件名
name = id + "#" + name;
// b. 得到上传目录
String basePath = getServletContext().getRealPath("/upload");
// c. 创建要上传的文件对象
File file = new File(basePath,name);
// d. 上传
item.write(file);
item.delete(); // 删除组件运行时产生的临时文件
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 2. 进入下载列表
*/
private void downList(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 实现思路:先获取upload目录下所有文件的文件名,再保存;跳转到down.jsp列表展示
//1. 初始化map集合Map<包含唯一标记的文件名, 简短文件名> ;
Map<String,String> fileNames = new HashMap<String,String>();
//2. 获取上传目录,及其下所有的文件的文件名
String bathPath = getServletContext().getRealPath("/upload");
// 目录
File file = new File(bathPath);
// 目录下,所有文件名
String list[] = file.list();
// 遍历,封装
if (list != null && list.length > 0){
for (int i=0; i<list.length; i++){
// 全名
String fileName = list[i];
// 短名
String shortName = fileName.substring(fileName.lastIndexOf("#")+1);
// 封装
fileNames.put(fileName, shortName);
}
}
// 3. 保存到request域
request.setAttribute("fileNames", fileNames);
// 4. 转发
request.getRequestDispatcher("/downlist.jsp").forward(request, response);
}
/**
* 3. 处理下载
*/
private void down(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取用户下载的文件名称(url地址后追加数据,get)
String fileName = request.getParameter("fileName");
fileName = new String(fileName.getBytes("ISO8859-1"),"UTF-8");
// 先获取上传目录路径
String basePath = getServletContext().getRealPath("/upload");
// 获取一个文件流
InputStream in = new FileInputStream(new File(basePath,fileName));
// 如果文件名是中文,需要进行url编码
fileName = URLEncoder.encode(fileName, "UTF-8");
// 设置下载的响应头
response.setHeader("content-disposition", "attachment;fileName=" + fileName);
// 获取response字节流
OutputStream out = response.getOutputStream();
byte[] b = new byte[1024];
int len = -1;
while ((len = in.read(b)) != -1){
out.write(b, 0, len);
}
// 关闭
out.close();
in.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}