说明:我本来不打算写一篇博客的,因为关于页面上传图片/文件这种博客太多了。但是我发现那些博客几乎一样,这不是关键,关键是代码有错,并且错都是一样的,这有点过分了,所以写下这篇博客,让更多人,少去找bug的麻烦,也是让我自己留个存档。
这里需要用到两个包:
没有的朋友可以去下载:(因为下载很简单,这里就不一一教大家了,点击下面的链接地址即可)
下面我贴出代码,大家复制之后改下包名应该就可以运行了。
为了减少代码的数量,这里我就把我写的几点重要说明提取出来了。
关于那个文件命名的地方我觉得直接放在代码中比较好就不写出来了。
//当初百度到的,没有右边这句代码,但是没有这句代码程序会报错 //savePath = savePath.replace("\\", "\\\\");
//上面自动获取的文件路径是用 \ 来划分的,但是很明显你去写个这样的字符串 aa\bb\dasd编译都会出错
//我们只要转义一下,但是为什么是 \\转义成 \\\\呢? 你可以去打印一下 System.out.println("\\"); 输出 \
//这个地方很多博客是这样么写的if(!file.exists() && file.isDirectory()){ }
//我真的怀疑那些抄写博客的都没有去运行一下代码,就直接复制了。
//file.isDirectory() API上描述是:测试此抽象路径名表示的文件是否是一个目录。
//你想正常情况只有两种,一个是这么目录我们已经创建。这种情况当然没问题。
//还有一种情况是,我们没有创建这个目录,我们需要下面的file.mkdir()这个方法来自动创建
//这样的话,没有目录。那这个方法返回的就是false 所以这个创建目录的方法当然不会执行。没有目录,下面的去复制到这个目录下,毫无疑问就是会报错了
UploadServlet.java的代码:
package servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
savePath = savePath.replace("\\", "\\\\");
File file = new File(savePath);
//判断上传文件的保存目录是否存在
if(!file.exists()){
//目录不存在需要创建目录
file.mkdir();
}
//上传提示消息
String message="";
try{
//使用apache文件上传组件处理文件上传步骤
//1、创建一个DiskFileItemFactory工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//2、创建一个文件上传解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//解决上传文件名的中文乱码
upload.setHeaderEncoding("UTF-8");
//3、判断提交上来的数据是否是上传表单的数据
if(!ServletFileUpload.isMultipartContent(request)) {
//按照传统方式获取数据
// request.getParameter(arg0);
return ;
}
//4、使用ServletFileUpload解析器上传数据,解析结果返回的是一个List<FileItem>集合
// 每一个FileItem对应一个Form表单的输入项
List<FileItem> list = upload.parseRequest(request);
for(FileItem item : list) {
//如果fileitem中封装的是普通输入项的数据 比如text password ...
if(item.isFormField()) {
String name = item.getFieldName();
//解决普通输入项的数据的中文乱码问题
String value = item.getString("UTF-8");
System.out.println(name +"=" + value);
}else { //如果fileitem中封装的是上传文件
String filename = item.getName();
System.out.println(filename);
if(filename == null || filename.trim().equals("")){
continue;
}
//注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名
是带有路径的如:c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
//下面两种文件名选一种即可
// --------------------------------第一种(和上传的文件名一样)--------------
//处理获取到的上传文件的文件名的路径部分,只保留文件名部分
// filename = filename.substring(filename.lastIndexOf("\\")+1);
// ----------------------第二种(自定义文件名我这里用的是UUID,主要是要获取源文件的扩展名称)
//获取图片的扩展名
filename = filename.substring(filename.lastIndexOf(".")+1);
//给文件重新取一个名字UUID
filename = UUID.randomUUID().toString()+"."+filename;
//获取item中的上传文件的输入流
InputStream in = item.getInputStream();
//创建一个文件输出流
FileOutputStream out = new FileOutputStream(savePath + "\\" + filename);
//创建一个缓冲区
byte[] buffer = new byte[1024];
//判断输入流中的数据是否已经读完的标识
int len = 0;
//循环将输入流读入到缓冲区当中,
while((len = in.read(buffer)) > 0) {
//使用FileOutputStream输入流将缓冲区的数据写入到指定的目录(savePath + "\\" +filename)
out.write(buffer,0,len);
}
//关闭流
in.close();
out.close();
//删除处理文件上传时生成的临时文件
item.delete();
message = "文件上传成功!!!";
}
}
} catch(Exception e) {
message = "文件上传失败!!!";
e.printStackTrace();
} finally {
request.setAttribute("message", message);
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
web.xml的代码:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>unploadanddownload</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>UploadServlet</display-name>
<servlet-name>UploadServlet</servlet-name>
<servlet-class>servlet.UploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UploadServlet</servlet-name>
<url-pattern>/UploadServlet</url-pattern>
</servlet-mapping>
</web-app>
message.jsp的代码
<code class="language-java"><%@ 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=ISO-8859-1">
<title>消息提示</title>
</head>
<body>
${message}
</body>
</html>
</code>
upload.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=ISO-8859-1">
<title>文件上传</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/UploadServlet"
enctype="multipart/form-data" method="post">
上传用户:<input type="text" name="username"> <br/>
上传文件1:<input type="file" name="file1"> <br/>
上传文件2:<input type="file" name="file2"> <br/>
<input type="submit" value="提交">
</form>
</body>
</html>