前段jsp代码(简单的表单):
<form action="${pageContext.request.contextPath}/Upload" enctype="multipart/form-data" method="post">
上传用户:<input type="text" name="username"><br>
上传文件:<input type="file" name="filename"><br>
<input type="submit" value="上传"><br>
</form>
后台servlet代码
需要导入commoms-fileupload和commoms-io包.
package lxb.upload;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
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.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
* Servlet implementation class Upload
*/
public class Upload extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
//设置编码格式
response.setCharacterEncoding("utf-8");
response.setContentType("text/html ; charset=utf-8");
try {
//设置上传文件类型
List<String> allowList = Arrays.asList(".jpg", ".avi", ".MOV");
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置缓冲大小和缓冲目录
factory.setSizeThreshold(1024*1024);
factory.setRepository(new File("d:\\2345\\"));
//创建上传解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//判断文件是否为普通文件
if (!upload.isMultipartContent(request)) {
return;
}
//设置最大文件上传
upload.setSizeMax(1024*1024*5);
//设置上传文件监听器
upload.setProgressListener(new ProgressListener() {
private int count = 0;
public void update(long pBytesRead, long pContentLength, int pItems) {
if (pBytesRead / (1024 * 1024) > count) {
count++;
System.out.println("已经解析了:" + count + "m了");
}
}
});
//解决文件名乱码问题
upload.setHeaderEncoding("UTF-8");
//解析上传文件
List<FileItem> list = upload.parseRequest(request);
//得到表单上传的每个文件
for (FileItem file : list) {
//判断是否为普通表单类型
if (file.isFormField()) {
String name = file.getFieldName();
//对表单传来的中文解析,解决乱码问题
//value = new String(value.getBytes("iso8859-1"), "UTF-8");(这种也可以)
String value = file.getString("UTF-8");
System.out.println(name+".........."+value);
}else{
//得到文件名
String fileName = file.getName();
//判断是否支持文件类型
if (!allowList.contains(fileName.substring(fileName.lastIndexOf(".")))) {
PrintWriter out = response.getWriter();
out.println("不支持文件类型");
return;
}
//生成随机目录和随机文件名
String path = makeName(fileName);
//文件流的传输,
InputStream is = file.getInputStream();
OutputStream os = new FileOutputStream(new File(path));
int len = 0;
byte[] buff = new byte[1024];
while ((len = is.read(buff)) > 0) {
os.write(buff, 0, len);
os.flush();
}
//关流很重要,输入流也要关,要不然删不掉临时文件,卡了很久才发现,
is.close();
os.close();
//删除临时文件
file.delete();
}
}
//提示
request.getRequestDispatcher("/message.jsp").forward(request, response);
} catch (FileUploadException e) {
request.getRequestDispatcher("message.jsp").forward(request, response);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
}
//生成随机文件路径和文件名
private String makeName(String fileName) {
int one = fileName.hashCode();
one = one & 15;
int two = fileName.hashCode();
two = (two >> 4) & 15;
String path = "d:\\2345\\" + one + File.separator + two + File.separator;
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
return path + File.separator + UUID.randomUUID().toString() + fileName;
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
总结
自己写代码才会发现很多问题,看着很简单的一个功能写了一天多,总算把功能基本写出来了。
不过还是有个问题没有解决,在设置了上传文件限制为5M后,如果上传超过5M的文件会提示访问页面出错,并且会发送多次请求,后台也不报错,先做一下记录,以后有能力在解决吧。