好久没有写东西,最近在做个项目,要用到文件h 传的,以前虽然也做上传,但是总觉得不好用 ,现在和队友合作做了一个带进度条的上传,觉得还行~~和大家分享一下。
首先说一下大概是这样实现的,在我们平时的上传表单里面,除了文件上传之外,也许还有其他的信息需要填写的,这样问题就来了:点击上传按钮之后,这个表单都封装并提交上去了,在上传完成后整个页面就跳转了。而且也不利于我们验证用户输入。很多人这样做的,把这2个操作分开,当然这样也行。。。
我们这样做:一个普通页面(可以用于填写所有信息的),一个文件上传页面,一个上传成功页面(这个不怎么重要)
然后关键的就是:把文件上传的页面嵌入到普通页面里面去,相当于说文件上传实际是由上传页面独立完成,信息填写页面也独立成功信息填写,这里我们用iframe。
不多说,上代码:
1、处理上传的Action
package org.yzsoft.upload.action;
import java.io.*;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport {
private static final int BUFFER_SIZE = 100;// 上传的字符流大小(单位:字节)
// 用File来封装上传文件域对象
private File file;
// 保存文件的目录路径(通过自动注入)
private static String ext; //文件后缀
private static String fileFileName;
private static float percent = 0;//百分比
// 自己封装的一个把源文件对象复制成目标文件对象
private static void copy(File src, File dst) {
InputStream in = null;
OutputStream out = null;
float completedSize = 0;//已经上传的大小
float fileSize = 0;//文件总大小
try {
in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE);
out = new BufferedOutputStream(new FileOutputStream(dst), BUFFER_SIZE);
fileSize = in.available();
byte[] buffer = new byte[BUFFER_SIZE];
int len = 0;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
completedSize += (long) len;
percent = completedSize / fileSize * 100;//百分比计算
}
} catch (Exception e) {
System.out.println(e);
} finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
System.out.println(e);
}
}
if (null != out) {
try {
out.close();
} catch (IOException e) {
System.out.println(e);
}
}
}
}
public String sumPre() { //计算后百分比输回页面
try {
PrintWriter out = ServletActionContext.getResponse().getWriter();
System.out.println(getFileFileName() + " filename");
out.print(percent);
} catch (IOException e) {
System.out.println("异常:" + e);
}
return null;
}
//上传的方法
public String upload() {
try {
if (percent >= 99.9) {//这里保险起见我们设百分比》99.9就清0,避免进度条到了100%就停在那里不动的尴尬
percent = 0;
}
File srcfile = this.getFile();// 自动注入的方法取得文件域的对象
// 根据服务器的文件保存地址和原文件名创建目录文件全路径
String uploadPath = ServletActionContext.getServletContext().getRealPath("upload");// 上传路径
ext = fileFileName.substring(fileFileName.lastIndexOf(".")).toLowerCase();// 取得后缀
System.out.println("取得后缀 " + ext);
File dstFile = new File(uploadPath, fileFileName);
copy(srcfile, dstFile);
} catch (Exception e) {
System.out.println(e);
}
return "success";
}
/**************/
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public String getFileFileName() {
return fileFileName;
}
public void setFileFileName(String fileFileName) {
this.fileFileName = fileFileName;
}
}
2、上传表单页面(就是我们平时普通的表单页面,样式有点乱。不理它了。嘻嘻~~~)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<form action="upload_doCreate.action" method="post" name="form" >
<table id="table2" width="99%" border="0" cellpadding="0" cellspacing="0">
<tr>
<th>文件上传</th>
</tr>
<tr>
<td ><table border="0" cellpadding="0" cellspacing="0" style="width:100%">
<tr>
<td align="left"> </td>
</tr>
<tr>
<td width="100%">
<table border="0" cellpadding="2" cellspacing="1" style="width:100%">
<tr>
<td align="right">文件名:</td>
<td><input type="text" id="filename" value=""/></td>
</tr>
<tr>
<td align="right">文件路径:</td>
<td><iframe style="width: 400px;height: 25px" scrolling='no' frameborder='0' resizable='no' allowtransparency='true' cellspacing='0' border='0' src='fileupload.jsp' id='iframeupload'></iframe></td>
</tr>
</table>
<br />
</td>
</tr>
</table></td>
</tr>
<tr>
<td colspan="2" align="center" height="50px">
<input type="Submit" name="Submit" value="保存" class="button" />
<input type="button" name="Submit2" value="返回" class="button" onclick="window.history.go(-1);"/></td>
</tr>
</table>
</form>
</body>
</html>
3、上传进度条页面(注意,这个是用一个iframe的源文件链接实现的)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<script type="text/javascript" src="jquery-1.6.2.min.js">
</script>
<style type="text/css">
<!--
body {
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
font-size: 14px;
}
-->
</style>
<script type="text/javascript">
function aa() {
$("#div1").hide();
$("#div2").show();
$.post("sumPre", {}, function(data) {//AJAX方式发送请求到Action的sumPre方法,计算后将百分比data返回来
$("#img").attr("width", parseInt(data) * 1.5);//设置进度条长度,这里*1.5只是为了把进度条显示长一点,好看一点
$("#p").html(parseInt(data) + "%");//进度百分比
});
window.setTimeout("aa()", 10);//定时执行
}
</script>
</head>
<body>
<div id="div1">
<form name='aform1' method='post' action="fileUpload.action"
enctype="multipart/form-data">
<input name='file' type='file' />
<input type="submit" value="上传" onclick="return aa();" />
</form>
</div>
<div id="div2" style="width: 400px; display: none;">
正在上传...
<img alt="" src="13221820.gif" width="16" height="16">
<img id="img" alt="" src="percent.jpg" width="1" height="5">
<span id="p" style="position: absolute; right: 30%; top: 0px;"></span>
</div>
</body>
</html>
4、上传成功后的页面(就是一个简单的页面)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<style type="text/css">
<!--
body {
margin-left: 0px;
margin-top: 5px;
margin-right: 0px;
margin-bottom: 0px;
font-size: 14px;
}
-->
</style>
</head>
<body>
上传成功
</body>
</html>
5、Struts.xml 配置文件
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<!-- Author: yzx -->
<struts>
<constant name="struts.multipart.maxSize" value="61440000000"></constant>
<package name="fileUpload" namespace="/" extends="struts-default">
<action name="fileUpload" class="org.yzsoft.upload.action.UploadAction" method="upload">
<result name="success">/filejd.jsp</result>
</action>
<action name="sumPre" class="org.yzsoft.upload.action.UploadAction" method="sumPre">
</action>
</package>
</struts>
接着:
我们在本机调试上传的时候,网页可能会有所卡顿,这个没关系,我们绑到服务器上就正常了,主要是浏览器处理文件的时候硬件性能问题。
总的来说,这个上传还是比较简单的(至少我这样认为~_~)
最后附上源码:欢迎大家多多交流,小弟这里先谢过啦~~~嘻嘻~~
分享到:
相关推荐
基于Andorid的音乐播放器项目改进版本设计实现源码,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。
uniapp-machine-learning-from-scratch-05.rar
game_patch_1.30.21.13250.pak
【毕业设计-java】springboot-vue计算机学院校友网源码(完整前后端+mysql+说明文档+LunW).zip
特征变换 特征选择
吸烟数据集 991张原始图片,平均识别率在88.3% coco json格式标注
c++万能头文件picture.h
spaceX 动力学分析
python教程学习
内容概要:本文详细整理了与uniapp有关的一系列学习资源及开发工具。首先对官方文档与教程进行梳理,这是学习uni-app的基础部分,涵盖从基本概念到具体开发指引的全方位资料。接着详细介绍了一款专为uni-app打造的高效开发工具HBuilderX的功能特点及其使用指南,并提到了CLI命令行工具可用于完成开发过程中的常规操作任务。同时,指出uni-app所处的强大社区氛围,无论是社区还是论坛都为开发者解决了实际遇到的问题并分享了大量有价值的经验;还提及多个专门为uni-app量身定制的UI框架和丰富的组件库,进一步提高了开发的便捷性和灵活性;最后列举了几类学习资源,诸如视频教程、博客与文章还有相关书籍均能助力新手成长为熟练工。所有这些资源都将有助于深入学习和理解uni-app这个跨平台框架的相关知识点,进而开发出优秀的多平台应用程序。 适用人群:有意进入跨平台移动应用开发领域的初学者,以及希望提升开发技能的专业人士。 使用场景及目标:为想要深入了解或者开始使用uni-app框架进行开发的人群提供完整路径指导;为目标受众建立起一套完整的学习路径来降低入门难度并提升实际操作能力。
AI Agent 行业研究报告.pdf
请到网盘中自取压缩包,此包为kibana-7.10.2 镜像压缩包,是通过现有镜像导出来的,主要是为了解决有些机器无法连接外网,导致无法下载镜像 加载镜像: docker load -i kibana-7.10.2.tar 查看镜像: docker images 备注:elk此镜像配套资源,相同版本的elasticsearch和logstash,请在我的资源中搜索其他镜像
图解AUTOSAR-CP-TcpIp逻辑图打包
【毕业设计-java】springboot-vue交友网站平台实现源码(完整前后端+mysql+说明文档+LunW).zip
海康相机平场矫正对比图
python教程学习
【论文+PPT+代码+开题+任务书】手机APP遥控的相关测试主要完成设计当中按键控制对应继电器是否正确打开以及关上,可以通过观察按下按键时继电器想匹配的LED是否点亮来进行验证。 进入手机APP后,根据APP中的按键分别控制不同的继电器,继电器1这个按键控制对应1号继电器的开启和关闭,手机蓝牙按下按键由OFF转变为ON那么电控制器件就可以变化一次,1号指示灯就可以由暗变亮了,再次按下手机蓝牙按键由ON转变为OFF电控制器件又变化一次,1号指示灯就可以由亮变暗。 如果点击继电器2则控制对应2号继电器的开启和关闭,手机蓝牙按下按键由OFF转变为ON那么电控制器件就可以变化一次,2号指示灯就可以由暗变亮了,再次按下手机蓝牙按键由ON转变为OFF电控制器件又变化一次,2号指示灯就可以由亮变暗。 如果点击继电器3则控制对应3号继电器的开启和关闭,手机蓝牙按下按键由OFF转变为ON那么电控制器件就可以变化一次,3号指示灯就可以由暗变亮了,再次按下手机蓝牙按键由ON转变为OFF电控制器件又变化一次,3号指示灯就可以由亮变暗。 如果点击继电器4则控制对应4号继电器的开启和关闭
【毕业设计】java-springboot+vue教师人事档案管理系统实现源码(完整前后端+mysql+说明文档+LunW).zip
ChatGPT付费创作系统V3.1.5独立版 WEB端+H5端+小程序端 (优化DeepSeek推理模型新增 阿里百炼、腾讯云、硅基流动接口) 是基于国外很火的ChatGPT进行开发的Ai智能多端系统。相比传统的问答系统, ChatGPT可以更加准确地理解用户的意图,提供更加精准的答案。同时系统采用了最新的GPT3.5接口与GPT4模型, 同时还支持DeepSeek,LocalAI、Claude3、豆包AI、文心一言,腾讯混元,讯飞星火,通义千问, 智普等等国内外各种大模型接口,视频音乐支持Pika、Runway、SunoAI接口,可以更好地适应不同的应用场景, 支持站点无限多开,支持WEB端、H5端、小程序端, 可以说ChatGPT付费创作系统目前国内相对体验比较好的一款的ChatGPT及多接口AI软件系统。 新增DeepSeek高级通道新增 阿里百炼、腾讯云、硅基流动3个接口、取消 国内AI通道 的敏感词过滤, 修复”高级版DeepSeek“计费bug,修复DeepSeek的上下文关联,支持AI接口输出的reasoning_content字段
如果你厌倦了繁琐的JDBC,阿帕奇的DBUtils又满足不了你的需求,mybaits、hibernate却又太过于庞大,那么就请使用cjxyorm吧,它吸收了DBUtils和Hibernate的特点,简单易用没有任何多余功能。轻轻松松的进行CRUD。