很久没有更新博客了,这段时间实在的忙的不可开交,项目马上就要上线了,要修补的东西太多了。当我在学习JavaWeb文件上传的时候,我就一直有一个疑问,网站上那些博客的图片是怎么上传的,因为当提交了表单之后网页就跳转了后。来我学习到了Ajax,我知道了浏览器可以异步的发送响应,这时我又有新的疑问,那就是在我上传一些文件的时候,那些网站的上传进度是怎么做到的,因为servlet直到上传完成之后才完成响应。
最近我们的项目中有一个地方中需要用到一个功能,当用户点击一个处理按钮时,前台会实时的显示后台处理动态,由于servlet一次只能接受一个请求,而且在servlet的生命周期结束时才会把响应数据发送到前台(这一点大家可以做个这样的测试:
response.getWriter () .print (“hello”); thread . sleep (10000); response.getWriter () .print(“世界”);
你们会发现前台在等待了约10 s后收到了“helloworld”),所以我想到了一个方法:使用单例保存实时信息。具体的实现方法就是,当用户点击了处理按钮时,在后台开启一个线程进行处理,并且每进行到一步,就向单例中写入当前状态信息,然后编写一个servlet,用于返回单例中的信息,前台循环发送请求,这样就能实现实时显示进度的效果。
好了,啰嗦了这么多,下面进入正题,如何实现上传文件动态显示进度,其实思想和上面的功能是一致的,我将这个功能分为三个点:
1。单例:用于保存进度信息;
2。上传servlet:用于上传文件并实时写入进度;
3。进度servlet:用于读取实时进度信息;
上代码,前台:
& lt; !DOCTYPE html> & lt; html> & lt; head> & lt;元charset=皍tf - 8”比; & lt; title>插入标题here & lt;风格类型=" text/css "比; {后#进展: 内容:‘%’; } & lt;/style> & lt;/head> & lt; body> & lt; h4>文件上传demo & lt;形式行动=" TestServlet " method=" post " enctype="多部分/格式" id=癲ataForm”比; & lt;输入类型="文件" name="文件" id=癴ileInput”比;& lt; br> & lt;输入类型="提交" value=" https://www.yisu.com/zixun/submit " id=疤峤弧北? & lt;/form> & lt; div id=敖健弊4? lt;/div> & lt;脚本type=" text/javascript " src=" https://www.yisu.com/zixun/scripts/jquery-1.9.1.min.js "祝辞& lt;/script> & lt;脚本type=" text/javascript祝辞 (函数(){ var形式=. getelementbyid (“dataForm”); var进步=. getelementbyid(“进步”); $(" #提交”).click(函数(事件){//阻止默认事件 事件。防止发生()://循环查看状态 var t=setInterval(函数(){ . ajax({美元 url:“ProgressServlet”, 类型:“文章”, 数据类型:“文本”, 数据:{ 文件名:fileInput.files [0] . name, }, 成功:函数(responseText) { var data=https://www.yisu.com/zixun/JSON.parse (responseText);//前台更新进度 的进步。innerText=实现方法(数据。进步/data.size) * 100); }, 错误:函数(){ console.log(“错误”); } }); }, 500);//上传文件 . ajax({美元 url:“UploadServlet”, 类型:“文章”, 数据类型:“文本”, 数据:新FormData(形式), processData:假的, contentType:假的, 成功:函数(responseText) {//上传完成,清除循环事件 clearInterval (t);//将进度更新至100% 的进步。innerText=100实现; }, 错误:函数(){ console.log(“错误”); } }); 返回错误; }); })(); & lt;/script> & lt;/body> & lt;/html> >之前后台,单例:
进口java.util.Hashtable; 公开课ProgressSingleton {//为了防止多用户并发,使用线程安全的散列表 私有静态Hashtable<对象,Object>表=new Hashtable<在(); 公共静态空放(对象,对象价值){ 表格put(关键字,值); } 公共静态对象(对象键){ 返回table.get(关键); } 公共静态对象删除(对象键){ 返回table.remove(关键); } } >之前上传servlet:
进口java.io.File; 进口java.io.FileOutputStream; 进口java.io.IOException; 进口java.io.InputStream; 进口并不知道; 进口javax.servlet.ServletException; 进口javax.servlet.annotation.WebServlet; 进口javax.servlet.http.HttpServlet; 进口javax.servlet.http.HttpServletRequest; 进口javax.servlet.http.HttpServletResponse; 进口org.apache.tomcat.util.http.fileupload.FileItem; 进口org.apache.tomcat.util.http.fileupload.FileUploadException; 进口org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory; 进口org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload; 进口org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext; 进口singleton.ProgressSingleton; @WebServlet ("/UploadServlet”) 公开课UploadServlet扩展HttpServlet { 私有静态最终长serialVersionUID l=1; 公共UploadServlet () { } 保护无效doGet (HttpServletRequest请求,HttpServletResponse响应)抛出ServletException IOException { DiskFileItemFactory工厂=new DiskFileItemFactory (); factory.setSizeThreshold (4 * 1024); ServletFileUpload上传=new ServletFileUpload(工厂); ListJavaWeb项目实现文件上传动态显示进度实例