客户端
html form表单:
表单中enctype="multipart/form-data"的意思,是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作.
HTML代码
<form name="myform" action="MyJsp.jsp" method="post"
enctype="multipart/form-data">
File1:<br>
<input type="file" name="myfile"><br>
File2:<br>
<input type="file" name="myfile"><br>
<br>
<input type="submit" name="submit" value="Commit">
</form>
服务器端
Apache的commons-fileupload.jar可方便的实现文件的上传功能,本例子通过导入这个commons-fileupload.jar。将Apache的commons-fileupload.jar放在应用程序的WEB-INF\lib下。
FileUpload 是基于 Commons IO的,所以在进入项目前先确定Commons IO的jar包在WEB-INF\lib下。
主要使用的如下:
FileItem-------DiskFileItemFactory-----ServletFileUpload
作用:
FileItem 用来封装表单中的元素和数据。
ServletFileUpload 处理表单数据,将数据封装到 FileItem 对象中。
DiskFileItemFactory FileItem 对象的工厂,可以设定缓冲区大小和存放临时文件目录。
ServletFileUpload 处理上传的文件的数据,优先保存在缓冲区,如果数据超过了缓冲区大小,则保存到硬盘上,存储在DiskFileItemFactory指定目录下的临时文件。数据都接收完后,它再在从临时文件中将数据写入到上传文件目录下的指定文件中,并删除临时文件。
功能:
限制上传文件的大小
long MAXSIZE=1024*1024*3; 单位是byte,所以这里指定的是3M
upload.setFileSizeMax(MAXSIZE);
设定临时目录
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024*1024); 设定了1M的缓冲区
factory.setRepository(new File("E:/temp")); 设置上传文件的临时目录
如果上传的文件小于1M,那么文件就在缓冲区中,然后写入硬盘,不经过缓冲区。这样也就不用硬盘的读写了,应该比较快。
定义服务器能接受的文件类型。
String[] allowTypes = new String[]{"jpg","jpeg"};
用数组定义可接受文件的后缀名,在读取表单内容后,取得客户端上传文件的全名,再截取后缀名,取到最后一个.的下标,再拿到之后所有的字符串:
String endName= fileName.substring(fileName.lastIndexOf(".")+1);
用数组遍历,如果不在数组中有定义,那么就不接受。
throw new RuntimeException("文件类型["+endName+"],不支持");
最基本的代码实现:
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List<FileItem> items = upload.parseRequest(request); //解析request请求
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) { //如果是表单域
,就是非文件上传元素
String name = item.getFieldName(); //获取name属性的值
String value = item.getString(); //获取value属性的值
} else {
String fieldName = item.getFieldName(); //文件域中name属性的值
String fileName = item.getName(); //文件的全路径,绝对路径名加文件名
String contentType = item.getContentType(); //文件的类型
long size = item.getSize(); //文件的大小,以字节为单位
File saveFile = new File("D:/test.jpg"); //定义一个file指向一个具体的文件
item.write(saveFile); //把上传的内容写到一个文件中
}
MyJsp.jsp代码
File uploadPath = new File("D:\\temp");//上传文件目录
if (!uploadPath.exists()) {
uploadPath.mkdirs();
}
// String uploadPath="D:\\temp";
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart == true) {
try {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(request);//得到所有的文件
Iterator<FileItem> itr = items.iterator();
while (itr.hasNext()) {//依次处理每个文件
FileItem item = (FileItem) itr.next();
String fileName = item.getName();//获得文件名,包括路径
if (fileName != null) {
File fullFile = new File(item.getName());
File savedFile = new File(uploadPath,
fullFile.getName());
item.write(savedFile);
}
}
out.print("upload succeed");
} catch (Exception e) {
e.printStackTrace();
}
} else {
out.println("the enctype must be multipart/form-data");
}