HTML5+J2EE实现文件异步上传
P.S. HTML5经过了W3C的8年努力,终于正式推广了。这次升级最大的就是升级了XMLHTTPRequest,让它变成了XMLHTTPRequest Level II(这有啥奇怪的?)。这个对象现在非常强大,可能会让所有使用jQuery的人全部重新拾起HTML原生的ajax技术。
闲话扯到这,接着是主题:我们今天要实现的就是下面的效果:
这里面文件名、文件大小和MIME都是在选择文件时读取和现实,然后点击上传之后,上传进度实时显示,最后弹出右边的对话框确认文件信息(当然这里我为了方便直接把文件信息压到POST请求里面了,否则可能乱码,你也可以试试服务器端直接读取)。
接着,看到了这个强大的效果,我们简单地分析以下思路。
1、我们首先确定实现方式:Javascript将会显示在客户端显示进度(用的是XMLHTTPRequest Level II的几个新的Event),然后同时上传文件信息和文件本身,当然是异步的。
2、服务器端用一个servlet就行,这里使用commonfileupload接受上传。
然后看一下新的XMLHTTPRequest Level II,看看如何监视这一过程。
<input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>
选择文件这里看到了一个onchange事件,这不是一个新事件,但在HTML5标准中被重新定义了,被用于文件被选择的时候调用。
function fileSelected() { //文件选择更改时调用的事件
var file = document.getElementById('fileToUpload').files[0]; //获得文件上传信息
if (file) { //如果用户选择了文件(没有选择的话,file就是null或是undefined,这样可以判断)
var fileSize = 0; //文件大小
if (file.size > 1024 * 1024) //如果文件大小大于1MB
fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100)
.toString()
+ 'MB'; //转换文件大小并以MB单位显示
else
//否则 fileSize = (Math.round(file.size * 100 / 1024) / 100).toString()
+ 'KB'; //否则用KB单位显示
document.getElementById('fileName').innerHTML = ' ' + file.name; //显示文件名信息
document.getElementById('fileSize').innerHTML = ' ' + fileSize; //显示文件大小信息
document.getElementById('fileType').innerHTML = ' ' + file.type; //显示文件MIME信息
}
}
这个注释不是我加的,我也不清楚是谁加的……但是大家应该能看懂了。
function uploadFile() { //点击上传按钮时的时间
var fd = new FormData(); //FormData是Html5的新增类
fd.append("file", document.getElementById('fileToUpload').files[0]); //向表单数据添加文件主体
var file = document.getElementById('fileToUpload').files[0]; //获得文件主体
var xhr = new XMLHttpRequest(); //初始化ajax请求
xhr.upload.addEventListener("progress", uploadProgress, false); //HTML5的新的事件,上传进度改变时,只能在有文件上传的情况下调用
xhr.addEventListener("load", uploadComplete, false); //老事件,上传完成后
xhr.addEventListener("error", uploadFailed, false); //出错时
xhr.addEventListener("abort", uploadCanceled, false); //中断时
var caption=document.getElementById("caption").value; //标题(和文件上传无关紧要)
fd.append("filename", file.name); //文件名添加到表单数据
fd.append("filesize", file.size); //文件尺寸添加到表单数据
fd.append("filetype", file.type); //MIME添加到表单数据
fd.append("caption", caption); //标题添加到表单数据
xhr.open("POST", "FileUpload",true); //准备上传
//xhr.setRequestHeader("Content-Type", "multipart/form-data"); //这句千万不能有!!!我也不知道为什么……
xhr.send(fd); //发出请求
}
点击上传按钮之后就是这段代码,FormData也是新加的对象,用于存储表单数据(某人加的注视应该够明白了……)。
接着我们看后台,后台使用commonfileupload接收(貌似说过了……),先把代码贴出来:
package Upload; import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List; import javax.servlet.ServletContext;
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.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload; import Log.LogManager; public class FileUpload extends HttpServlet { /**
* Constructor of the object.
*/
public FileUpload() {
super();
} /**
* Destruction of the servlet. <br>
*/
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
} /**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { try {
request.setCharacterEncoding("UTF-8");
DiskFileItemFactory fif=new DiskFileItemFactory();
fif.setSizeThreshold(1024*1024);
ServletFileUpload sfu=new ServletFileUpload(fif);
sfu.setSizeMax(1024*1024*1024);
List items=null;
try {
items=sfu.parseRequest(request);
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Iterator iter=items.iterator();
String filename="";
String filesize="";
String filetype="";
String caption="";
FileItem fi=null;
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {
String name=item.getFieldName();
if(name.equals("filename")==true){
filename=item.getString("UTF-8");
}else if(name.equals("filesize")==true){
filesize=item.getString("UTF-8");
}else if(name.equals("filetype")==true){
filetype=item.getString("UTF-8");
}else if(name.equals("caption")==true){
caption=item.getString("UTF-8");
}
} else {
fi=item;
}
}
ServletContext application=getServletContext();
String path=(String) application.getAttribute("datapath")+"uploadpath"+application.getAttribute("systempi")+filename;
File f1=new File(path);
try {
fi.write(f1);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("你上传了一个文件到服务器,下面将核实这些信息:");
out.println("1、文件名:"+filename);
out.println("2、文件大小:"+filesize);
out.println("3、文件MIME类型:"+filetype);
out.println("如果信息全部正确,说明文件成功上传了!");
String sqls1="";
LogManager.log("一个文件上传请求已经被受理!文件存储于:"+path);
out.flush();
out.close();
} catch (Exception e) {
LogManager.err(e.toString());
}
} /**
* Initialization of the servlet. <br>
*
* @throws ServletException if an error occurs
*/
public void init() throws ServletException {
// Put your code here
} }
还挺简单的,对吗?处理HTML5的上传请求和处理以前版本的上传请求基本一样,唯一需要注意的是:原来是你来拼接请求,所以说,位置由你决定,现在FormData拼接请求的字符串中项目的顺序和append的顺序有关,所以别搞错了(貌似我就搞错了,先添加了文件,然后在后台补救了一下……)。
基本上就这些代码,然后就是添加文件信息到数据库什么的,具体上传步骤查查commonfileupload的api好了。
整个项目不方便让大家下载,但这是一个OJ项目里面的,有兴趣的关注一下进入项目的git。另外如果转载的话,注明一下,谢谢!
HTML5+J2EE实现文件异步上传的更多相关文章
- HTML5实现图片文件异步上传
原文:HTML5实现图片文件异步上传 利用HTML5的新特点做文件异步上传非常简单方便,本文主要展示JS部分,html结构.下面的代码并未使用第三发库,如果有参照,请注意一些未展现出来的代码片段.我这 ...
- MVC文件上传04-使用客户端jQuery-File-Upload插件和服务端Backload组件实现多文件异步上传
本篇使用客户端jQuery-File-Upload插件和服务端Badkload组件实现多文件异步上传.MVC文件上传相关兄弟篇: MVC文件上传01-使用jquery异步上传并客户端验证类型和大小 ...
- 文件的上传(表单上传和ajax文件异步上传)
项目中用户上传总是少不了的,下面就主要的列举一下表单上传和ajax上传!注意: context.Request.Files不适合对大文件进行操作,下面列举的主要对于小文件上传的处理! 资源下载: 一. ...
- js 文件异步上传 显示进度条 显示上传速度 预览文件
通常文件异步提交有几个关键 1.支持拖拽放入文件.2.限制文件格式.3.预览图片文件.4.上传进度,速度等,上传途中取消上传.5.数据与文件同时上传 现在开始笔记: 需要一个最基础的元素<inp ...
- 普通文件的上传(表单上传和ajax文件异步上传)
一.表单上传: html客户端部分: <form action="upload.ashx" method="post" enctype="mul ...
- SpringMVC + AJAX 实现多文件异步上传
转自:https://www.jianshu.com/p/f3987f0f471f 今天,我就这个问题来写一篇如何用 SpringMVC + AJAX 实现的多文件异步上传功能.基本的代码还是沿用上篇 ...
- 文件的上传(1)(表单上传和ajax文件异步上传)
文件的上传(表单上传和ajax文件异步上传) 项目中用户上传总是少不了的,下面就主要的列举一下表单上传和ajax上传!注意: context.Request.Files不适合对大文件进行操作,下面列举 ...
- 小程序使用 Promise.all 完成文件异步上传
小程序使用 Promise.all 完成文件异步上传 extends [微信小程序开发技巧总结(二) -- 文件的选取.移动.上传和下载 - Kindear - 博客园 (cnblogs.com)] ...
- HTML5 文件异步上传 — h5uploader.js
原文地址:http://imziv.com/blog/article/read.htm?id=62 之前写过一篇H5异步文件上传的文章, 但是很多朋友看着我的这个教程还是出现很多问题,文章写的不是很好 ...
随机推荐
- delphi 选中的展开0级 子级不展开
TreeView1.Selected.Expand(False); //选中的展开0级 子级不展开 TreeView1.Selected.Expand(True); //全部展开 来自为知笔记(Wiz ...
- oracle internal: VIEW: X$KCBKPFS - PreFetch Statistics - (9.0)
WebIV:View NOTE:159898.1 Note (Sure) - Note Mods - Note Refs Error ORA 600 TAR TAR-Info Bug B ...
- [MEAN Stack] First API -- 4. Organize app structure
The app structure: Front-end: app.js /** * Created by Answer1215 on 12/9/2014. */ 'use strict'; func ...
- mysql 5.7.12 新增 X plugin 详解
https://dev.mysql.com/doc/refman/5.7/en/document-store.html 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息 ...
- 一个坐标点围绕任意中心点旋转--C#实现
假设对图片上任意点(x,y),绕一个坐标点(rx0,ry0)逆时针旋转RotaryAngle角度后的新的坐标设为(x', y'),有公式: x'= (x - rx0)*cos(RotaryAngle) ...
- Maven学习小结(七 生命周期[转])
Maven2的阶段(生命周期)说明:Maven2拥有三套独立的生命周期,Maven的命令也是基于这些生命周期来说的.1.clean:清理先前构建的构件,又分为下面三个下阶段: a.pre-clean ...
- Direct3D11-1 初始化
在使用一个东西之前,我们需要初始化他,好比汽车加油,手机充电.于是我们采取平时的编码习惯,试图写下如下代码 Direct3D11 _direct3d11; 事实上,我们 ...
- log4j个人使用整理
Log4j介绍: 略过. 配置: Eclipse项目中添加log4j.jar到lib下. 在bin目录下新建log4j.properties,编辑好log4j配置文件. 样例分析: log4j.roo ...
- Mysql 复习
1.my.ini :mysql 配置文件 [client]#password = your_passwordport = 3306socket = /tmp/mysq ...
- ARM Linux bootloader笔记
.text //指定了后续编译出来的内容放在代码段[可执行] .global //告诉编译器后续跟的是一个全局可见的名字[可能是变量,也可以是函数名] _start /*函数的其实地址,也是编译.链接 ...