一、Servlet文件上传
1.上传jsp页面[上传到fileResult.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>上传文件</title>
</head>
<body>
<form action="fileResult.jsp" method="post" enctype="multipart/form-data">
<!--method必须设为post,因为get有最大限度256k,太大就带不上去-->
<!--enctype="multipart/form-data"上传的是多种类型数据,不再只是文本.也就是说当去掉这个标签,传递的便是文本[传输文件的文件名]-->
username:<input type="text" name="username"/><br/>
file1:<input type="file" name="file1"/><br/>
<input type="submit" value="submit"/>
</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*,java.io.*" %><!--导入包-->
<!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>上传结果</title>
</head>
<body>
<!--上传http协议,底层是tcp协议。tcp协议是有连接的,可以获得流-->
<%
InputStream is = request.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String buffer = null;
while(null != (buffer=br.readLine())){
out.print(buffer+"<br/>");//读取流中的数据
}
//需要关两个流,因为字节输入流是通过request中获取的
br.close();
is.close();
%>
<!--取文本的方式,无法获取文件...-->
<!--username:<%=request.getParameter("username") %>
file1:<%=request.getParameter("file1") %>-->
</body>
</html>
输出流中打印的信息
2.Servlet上传[导入commons-fileupload-1.2.2.jar、commons-io-2.0.1.jar,在WebRoot下创建upload文件夹保存上传的文件]
<%@ 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>上传文件</title>
</head>
<body>
<form action="servlet/FileUploadServlet" method="post" enctype="multipart/form-data">
<!--上传到指定的servlet类中-->
username:<input type="text" name="username"/><br/>
file1:<input type="file" name="file1"/><br/>
<input type="submit" value="submit"/>
</form>
</body>
</html>
servlet类
package com.struts.servlet;
import java.io.File;
import java.io.IOException;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class FileUploadServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
// 获得保存上传文件路径,在webRoot下的upload
String path = request.getRealPath("/upload");
System.out.println("path=" + path);
// 确定文件上传到的路径
DiskFileItemFactory factory = new DiskFileItemFactory();
// 相当于上传文件的仓库,存放上传文件 这里的File是目录
factory.setRepository(new File(path));
// 如果上传的文件比较小,先放在内存中,再放到保存路径中
// 如果上传的文件比较大,内存不能满足,先放在缓存区中,在保存到指定路径中
// 上传多大时需要使用缓冲区,可以通过setSizeThreshold()设置
factory.setSizeThreshold(1024 * 1024);
// 文件上传
ServletFileUpload upload = new ServletFileUpload(factory);
try {
// 将客户端发送过来的请求进行解析
List<FileItem> list = (List<FileItem>) upload.parseRequest(request);
// list中存储的是传过来的多个文件、多个文本
for (FileItem item : list) {
String name = item.getFieldName();
if (item.isFormField()) {// 如果是属性,也就是文本标签而并非文件
String value = item.getString();
System.out.println(name + "=" + value);
request.setAttribute(name, value);
} else {
// 上传文件
// 获得文件名,一般浏览器解析文件名后只要文件名,
// 而一些浏览器解析方式不同,会将全部文件整个路径输出,
//对于这些浏览器的解析方式做些处理
String value = item.getName();
//当文件名为全路径时,从后往前取到的第一个\之后便是文件名
//若文件名并非全路径时,从后往前取第一个\是取不到的,返回-1,-1+1=0,从第0位开始取文件名也是对的
//file1=C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg
//file1=Chrysanthemum.jpg
int start = value.lastIndexOf("\\");
System.out.println("start:"+start);
String fileName = value.substring(start+1);
request.setAttribute(name, fileName);
System.out.println(name + "=" + value);
System.out.println(name + "=" + fileName);
//将文件写到指定的路径中(路径下面创建一个文件)
item.write(new File(path,fileName));
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
//跳转到指定的页面
request.getRequestDispatcher("/fileResult.jsp").forward(request,response);
}
}
package com.struts.servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class FileUploadServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
// 获得保存上传文件路径,在webRoot下的upload
String path = request.getRealPath("/upload");
System.out.println("path=" + path);
// 确定文件上传到的路径
DiskFileItemFactory factory = new DiskFileItemFactory();
// 相当于上传文件的仓库,存放上传文件 这里的File是目录
factory.setRepository(new File(path));
// 如果上传的文件比较小,先放在内存中,再放到保存路径中
// 如果上传的文件比较大,内存不能满足,先放在缓存区中,在保存到指定路径中
// 上传多大时需要使用缓冲区,可以通过setSizeThreshold()设置
factory.setSizeThreshold(1024 * 1024);
// 文件上传
ServletFileUpload upload = new ServletFileUpload(factory);
try {
// 将客户端发送过来的请求进行解析
List<FileItem> list = (List<FileItem>) upload.parseRequest(request);
// list中存储的是传过来的多个文件、多个文本
for (FileItem item : list) {
String name = item.getFieldName();
if (item.isFormField()) {// 如果是属性,也就是文本标签而并非文件
String value = item.getString();
System.out.println(name + "=" + value);
request.setAttribute(name, value);
} else {
// 上传文件
// 获得文件名,一般浏览器解析文件名后只要文件名,
// 而一些浏览器解析方式不同,会将全部文件整个路径输出,
//对于这些浏览器的解析方式做些处理
String value = item.getName();
//当文件名为全路径时,从后往前取到的第一个\之后便是文件名
//若文件名并非全路径时,从后往前取第一个\是取不到的,返回-1,-1+1=0,从第0位开始取文件名也是对的
//file1=C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg
//file1=Chrysanthemum.jpg
int start = value.lastIndexOf("\\");
System.out.println("start:"+start);
String fileName = value.substring(start+1);
request.setAttribute(name, fileName);
System.out.println(name + "=" + value);
System.out.println(name + "=" + fileName);
//将文件写到指定的路径中(路径下面创建一个文件)
//item.write(new File(path,fileName));
//自定义输出
OutputStream os = new FileOutputStream(new File(path,fileName));
InputStream is = item.getInputStream();
byte[] buffer = new byte[400];
int length = 0;
while(-1!=(length=is.read(buffer))){
os.write(buffer,0,length);
}
is.close();
os.close();
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
//跳转到指定的页面
request.getRequestDispatcher("/fileResult.jsp").forward(request,response);
}
}
对比item.write(new File(path,fileName));与自定义输出的差别
自定义输出大文件时,传入文件的同时会创建一个临时文件。而使用item.write()方法时,内部完成了把后缀名为tmp的文件删除
//item.getSize()获得文件传输长度,可以通过ajax动态调用,比对文件大小与传输大小,获得文件传输进度