最近在做文件上传的相关工作,使用了H5的FormData,到后台就不知到怎么能得到前端上传的数据,这里找到了一种方式,使用ServletFileUpload实现,此前需要导入包,在下面的链接中可以找到。
原文链接。
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 针对post请求,设置允许接收中文
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
try {
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("UTF-8");
List items = upload.parseRequest(request);
Map params = new HashMap();
for(Object object:items){
FileItem fileItem = (FileItem) object;
if (fileItem.isFormField()) {
//这里就相当与FormData中的key,value
params.put(fileItem.getFieldName(), fileItem.getString("utf-8"));//如果你页面编码是utf-8的
}
}
//使用params.get获取参数值 send_time就是key
String val = (String) params.get("key");
} catch (FileUploadException e1) {
e1.printStackTrace();
}
}
又找到一个详细的解释,原文链接:
文件上传的前提
1.form表单的method必须是post
2.form表单的enctype必须是multipart/form-data 以二进制字节流
进行提交 传统接收参数的方式无效
DiskFileItemFactory:环境
void setSizeThreshold(int sizeThreshold)
设置缓冲区大小,默认10KB 超出将使用临时文件上传
void setRepository(File repository)
设置临时文件路径
ServletFileUpload:核心操作类
public void setSizeMax(long sizeMax)设置总文件的大小
public void setFileSizeMax(long fileSizeMax):设置单个文件的大小
public List parseRequest(javax.servlet.http.HttpServletRequest req)
解析请求正文内容
public static boolean isMultipartContent(HttpServletRequest req)//判断enctype
FileItem:输入域
boolean isFormField():判断是否是普通字段
String getName():获取上传文件名
String getFieldName():获取普通字段的字段名
String getString():获取普通字段的值
String getContentType() 获得文件类型
InputStream getInputStream()以流的形式返回上传文件的主体内容
void delete()删除临时文件
文件上传中需要注意的问题
1.保证安全
上传文件放在WEB-INF目录中
2.中文乱码问题
普通字段乱码
String fieldValue = item.getString("GBK");
文件名乱码
request.setCharacterEncoding("GBK");
3.重名文件覆盖
1.UUID
2.使用文件上传日期分类存储
3.System.currentMillions()
4.限制文件上传类型
1.endsWith("")这种方式不可取
2.判断其mime类型 getContentType()
5.限制用户上传文件的大小
1.限制单个上传文件的大小
upload.setFileSizeMax(4*1024*1024);
2.限制总文件大小
upload.setSizeMax()
6.临时文件
item.delete();
7.多个文件上传时,没有上传内容的问题
if(fileName==null||"".equals(fileName.trim())){
continue;
}
8.上传进度检测
upload.setProgressListener(new ProgressListener(){
参数一:已上传的字节数
参数二:总字节数
参数三:第几项
@Override
public void update(long arg0, long arg1, int arg2) {
// TODO Auto-generated method stub
System.out.println(arg0+" "+arg1+" "+arg2);
}
});
package cn.gs.ly;
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.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class FileUploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
//得到上传文件的保存目录。 将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
String realPath = this.getServletContext().getRealPath("/upload");// /WEB-INF/files
System.out.println("文件存放位置:"+realPath);
//设置临时目录。 上传文件大于缓冲区则先放于临时目录中
String tempPath = "E:\\tempPath";
System.out.println("临时文件存放位置:"+tempPath);
//判断存放上传文件的目录是否存在(不存在则创建)
File f = new File(realPath);
if(!f.exists()&&!f.isDirectory()){
System.out.println("目录或文件不存在! 创建目标目录。");
f.mkdir();
}
//判断临时目录是否存在(不存在则创建)
File f1 = new File(tempPath);
if(!f1.isDirectory()){
System.out.println("临时文件目录不存在! 创建临时文件目录");
f1.mkdir();
}
/**
* 使用Apache文件上传组件处理文件上传步骤:
*
* */
//1、设置环境:创建一个DiskFileItemFactory工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置上传文件的临时目录
factory.setRepository(f1);
//2、核心操作类:创建一个文件上传解析器。
ServletFileUpload upload = new ServletFileUpload(factory);
//解决上传"文件名"的中文乱码
upload.setHeaderEncoding("UTF-8");
//3、判断enctype:判断提交上来的数据是否是上传表单的数据
if(!ServletFileUpload.isMultipartContent(req)){
System.out.println("不是上传文件,终止");
//按照传统方式获取数据
return;
}
//==获取输入项==
// //限制单个上传文件大小(5M)
// upload.setFileSizeMax(1024*1024*4);
// //限制总上传文件大小(10M)
// upload.setSizeMax(1024*1024*6);
//4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
List<FileItem> items =upload.parseRequest(req);
for(FileItem item:items){
//如果fileitem中封装的是普通输入项的数据(输出名、值)
if(item.isFormField()){
String filedName = item.getFieldName();//普通输入项数据的名
//解决普通输入项的数据的中文乱码问题
String filedValue = item.getString("UTF-8");//普通输入项的值
System.out.println("普通字段:"+filedName+"=="+filedValue);
}else{
//如果fileitem中封装的是上传文件,得到上传的文件名称,
String fileName = item.getName();//上传文件的名
//多个文件上传输入框有空 的 异常处理
if(fileName==null||"".equals(fileName.trim())){ //去空格是否为空
continue;// 为空,跳过当次循环, 第一个没输入则跳过可以继续输入第二个
}
//注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如: c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
//处理上传文件的文件名的路径,截取字符串只保留文件名部分。//截取留最后一个"\"之后,+1截取向右移一位("\a.txt"-->"a.txt")
fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
//拼接上传路径。存放路径+上传的文件名
String filePath = realPath+"\\"+fileName;
//构建输入输出流
InputStream in = item.getInputStream(); //获取item中的上传文件的输入流
OutputStream out = new FileOutputStream(filePath); //创建一个文件输出流
//创建一个缓冲区
byte b[] = new byte[1024];
//判断输入流中的数据是否已经读完的标识
int len = -1;
//循环将输入流读入到缓冲区当中,(len=in.read(buffer))!=-1就表示in里面还有数据
while((len=in.read(b))!=-1){ //没数据了返回-1
//使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath+"\\"+filename)当中
out.write(b, 0, len);
}
//关闭流
out.close();
in.close();
//删除临时文件
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
item.delete();//删除处理文件上传时生成的临时文件
System.out.println("文件上传成功");
}
}
} catch (FileUploadException e) {
//e.printStackTrace();
throw new RuntimeException("服务器繁忙,文件上传失败");
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}