struts2实现多文件上传的示例代码
开发环境JDK1.8 eclipse struts2-2.3.31
1.创建web项目
2.导入struts2核心jar包
3.更改web.xml配置文件(只要配置好struts2的Filter就好)
4.创建src/struts.xml文件
代码如下 | 复制代码 |
<?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts> <!-- 该属性指定需要Struts2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。 如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。 --> <constantname="struts.action.extension"value="do"/> <!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 --> <constantname="struts.serve.static.browserCache"value="false"/> <!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 --> <constantname="struts.configuration.xml.reload"value="true"/> <!-- 开发模式下使用,这样可以打印出更详细的错误信息 --> <constantname="struts.devMode"value="true"/> <!-- 默认的视图主题 --> <constantname="struts.ui.theme"value="simple"/> <!--<constant name="struts.objectFactory" value="spring" />--> <!--解决乱码 --> <constantname="struts.i18n.encoding"value="UTF-8"/> <!-- 指定允许上传的文件最大字节数。默认值是2097152(2M) --> <constantname="struts.multipart.maxSize"value="10701096"/> <!-- 设置上传文件的临时文件夹,默认使用javax.servlet.context.tempdir --> <constantname="struts.multipart.saveDir "value="d:/tmp"/>
<packagename="upload"extends="struts-default"> <actionname="fileUpload"class="com.ifan.action.FileUpload"> <!-- 动态设置savePath的属性值 --> <paramname="savePath">WEB-INF/images</param> <resultname="success">/success.jsp</result> <resultname="input">/error.jsp</result> <interceptor-refname="fileUpload"> <!-- 文件过滤 --> <paramname="allowedTypes">image/bmp,image/png,image/gif,image/jpeg</param> <!-- 文件大小, 以字节为单位 --> <paramname="maximumSize">1025956</param> </interceptor-ref> <!-- 默认拦截器必须放在fileUpload之后,否则无效 --> <interceptor-refname="defaultStack"/> </action> </package> </struts> |
5.创建src/com.ifan.action.FileUpload.Java
代码如下 | 复制代码 |
packagecom.ifan.action;
importjava.io.File;
importorg.apache.commons.io.FileUtils; importorg.apache.struts2.ServletActionContext;
importcom.opensymphony.xwork2.ActionContext; importcom.opensymphony.xwork2.ActionSupport;
publicclassFileUploadextendsActionSupport{
privateFile[] image;//上传的文件 privateString[] imageFileName;//文件名称 privateString[] imageContentType;//文件类型
publicString execute()throwsException { ServletActionContext.getRequest().setCharacterEncoding("UTF-8"); String realpath = ServletActionContext.getServletContext().getRealPath("/images"); System.out.println(realpath); if(image !=null) { File savedir=newFile(realpath); if(!savedir.getParentFile().exists()) savedir.getParentFile().mkdirs(); for(inti=0;i<image.length;i++){ File savefile =newFile(savedir, imageFileName[i]); FileUtils.copyFile(image[i], savefile); } ActionContext.getContext().put("message","文件上传成功"); } return"success"; }
publicFile[] getImage() { returnimage; }
publicvoidsetImage(File[] image) { this.image = image; }
publicString[] getImageContentType() { returnimageContentType; }
publicvoidsetImageContentType(String[] imageContentType) { this.imageContentType = imageContentType; }
publicString[] getImageFileName() { returnimageFileName; }
publicvoidsetImageFileName(String[] imageFileName) { this.imageFileName = imageFileName; } } |
6.创建WebContent/index.jsp ,作为上传文件的页面
代码如下 | 复制代码 |
<%@ page language="java"import="java.util.*"pageEncoding="UTF-8"%> <%@ taglib prefix="s"uri="/struts-tags"%> <% 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%>"rel="external nofollow">
<title>My JSP'hello.jsp'starting page</title>
<meta http-equiv="pragma"content="no-cache"> <meta http-equiv="cache-control"content="no-cache"> <meta http-equiv="expires"content="0"> <meta http-equiv="keywords"content="keyword1,keyword2,keyword3"> <meta http-equiv="description"content="This is my page"> <!-- <link rel="stylesheet"type="text/css"href="styles.css"rel="external nofollow"> -->
</head>
<body> <!-- Struts2的文件上传标签 --> <s:form action="fileUpload"namespace="/"method="POST"enctype="multipart/form-data"> <!-- 该name需要和后台的File类型的名字对应起来,否则将得不到该文件 size 上传文件的大小 --> <s:file name="image"label="Select a File to upload"size="40"/> <s:file name="image"label="Select a File to upload"size="40"/> <s:submit value="submit"name="submit"/>
</s:form>
</body> </html> |
7.创建WebContent/success.jsp 作为文件上传成功跳转的页面,创建WebContent/error.jsp 作为文件上传失败的页面 , 创建WebContent/images文件夹,作为上传文件的存储位置
本文介绍了Swift实现无限轮播效果的教程,文中给出了详细的实例代码,不会的朋友可以看看从今天开始,我学习的重点开始转向Swift,并且会分享一些自己学习的心得体会,今天给大家带来的的是无限轮播。广告页的无限轮播是非常常见的一个功能,大多数APP都有,大多数程序员也都实现过,今天我们用Swift实现一下。项目地址
图片切换我们可以选择的基本控件有两个UIScrollView 和 UICollectionView,这次我们选择UICollectionView;既然是轮播,就会用到Timer。所以,我们这次主要应用的知识点为UICollectionView 和 Timer;
代码如下 | 复制代码 |
import UIKit
classCycleScrollView: UIView, UICollectionViewDelegate,UICollectionViewDataSource {
var bottomView : UICollectionView? var width : CGFloat? var height : CGFloat? var timer : Timer?
override init(frame: CGRect){
super.init(frame: frame) // 1.设置背景色 self.backgroundColor = UIColor.clear // 2.设置宽高 width = self.frame.size.width height = self.frame.size.height // 3.添加bottomView setupBottomView() // 4.添加定时器 setupTimer() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
func setupBottomView() {
// 5.设置collectionView的布局 let flowLayout = UICollectionViewFlowLayout(); flowLayout.itemSize = self.bounds.size flowLayout.minimumLineSpacing = 0; flowLayout.minimumInteritemSpacing = 0; flowLayout.scrollDirection = UICollectionViewScrollDirection.horizontal; bottomView = UICollectionView.init(frame: self.bounds, collectionViewLayout: flowLayout) self.addSubview(bottomView!); // 6.设置collectionView的尺寸 bottomView?.contentSize = CGSize(width:width! * CGFloat(4),height:height!) // 7.分页 bottomView?.isPagingEnabled =true // 8.去掉滚动条 bottomView?.showsVerticalScrollIndicator =false bottomView?.showsHorizontalScrollIndicator =false // 9.设置代理 bottomView?.delegate = self bottomView?.dataSource = self // 10.注册cell bottomView?.register(UICollectionViewCell().classForCoder, forCellWithReuseIdentifier:"ID"); if#available(iOS 10.0, *) { // 11.预加载 bottomView?.isPrefetchingEnabled =true }else{ // Fallback on earlier versions } } func setupTimer() { // 12.实例化定时器 timer = Timer.init(timeInterval: 2, target: self, selector: #selector(timerAction), userInfo: nil, repeats:true); RunLoop.main.add(timer!, forMode: RunLoopMode.defaultRunLoopMode);
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
self.timer?.fire(); } } func timerAction() {
var contentOffsetX = (self.bottomView?.contentOffset.x)! + self.frame.size.width
ifcontentOffsetX > self.frame.size.width * 3 { // 当前视图显示的是第三个的时候,设置bottomView的偏移量为0 self.bottomView?.contentOffset = CGPoint(x:0,y:0) contentOffsetX = self.frame.size.width } self.bottomView?.setContentOffset(CGPoint(x:contentOffsetX,y:0), animated:true) } // 重写removeFromSuperview方法,用于删除定时器,否则定时器一直存在,浪费内存 override func removeFromSuperview() {
timer?.invalidate() timer = nil super.removeFromSuperview() } // Mark:UICollectionViewDataSource // 设置Itmes func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return4; } // 设置cell func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell : UICollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier:"ID",for: indexPath) forview : UIView in cell.contentView.subviews {
view.removeFromSuperview() } let imageView = UIImageView.init(frame: cell.contentView.bounds) ifindexPath.row < 3 {
imageView.image = UIImage.init(named: String(indexPath.row))
}else{ imageView.image = UIImage.init(named: String(0)) } cell.contentView.addSubview(imageView)
returncell; } // Mark:UICollectionViewDelegate // 点击方法 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("您点击了第 \(indexPath.row == 3 ? 0 : indexPath.row) 个"); }
} |
UICollectionView 和 Timer的用法和OC基本相同。Swift和OC的UI部分应该是一致的,因为底层都是OpenGL。我直接说一下区别:
1.Timer:如果重复,OC是等一个间隔再执行的,Swift是立即执行的,所以我用了GCD延时开启定时器。
2.Swift 没有 CGPointZero。
无限轮播的原理就是在最后面多添加一个和第一个相同的itme。当你滑动到最后一个itme时,把UICollectionView的contentOffset置零,继续向右活动。如果不添加,会给用户一种卡顿的感觉。
本文给大家介绍了html+javascript+bootstrap实现层级多选框全层全选和多选功能的实现代码,非常有用,不回的小伙伴快来看看吧想做一个先按层级排序并可以多选的功能,首先倾向于用多层标签式的,直接选定加在文本域里, 查到这文,非常详细,如果大家需要做前面所说的功能,可以参考这个地址,http://mrthink.net/jquery-plugin-iselecttags/
但是,考虑到如果要做一个选项数不确定、可能非常多,用标签会容易视觉疲劳,同时要求随着选项数的变化,最小程度影响网页布局和效果,于是选择用层级的多选框,也就是设置电脑的那种常见效果。第二层选项可以折叠/展开到第一层下面,用bootstrap的 data-toggle="collapse" data-target="#demo1"
进行关联第二层折叠效果。
具体代码如下:
|
用Html实现人人网注册界面 ,Js实现生日栏表单三级联动
1. 效果
2.Html代码部分
代码如下 | 复制代码 |
<!DOCTYPE html> <html> <headlang="en"> <metacharset="UTF-8"> <title>人人网日期表单联动</title> <style> select { font:20px/40px '宋体'; } option {width: 100px;} </style> </head> <body> <formmethod="get"onchange="changeMonth()"> <b><h3align="center"> 免费开通人人网账号
</h3></b>
<tablealign="center"height="500">
<tr><td>注册邮箱: </td><td> <inputtype="text"name="name"/></td></tr> <tr><td> </td><td>你还可以使用 <ahref="https://www.baidu.com">账号</a> 注册或者 <ahref="https://www.baidu.com">手机号</a> 注册</td></tr>
<tr><td>创建密码: </td><td><inputtype="password"name="password"/></td></tr>
<tr><td>真实姓名: </td><td><inputtype="password"name="name"/></td>
<tr><tdalign="right">性别: </td><td>男<inputtype="radio"value="male"name="gender"/> 女<inputtype="radio"value="female"name="gender"/></td></tr>
<tr><tdalign="right">生日: </td><td>
<divid="box"> <selectname="sel1"id="sel1"> <optionvalue="year">年</option> </select> <selectname="sel2"id="sel2"> <optionvalue="month">月</option> </select> <selectname="sel3"id="sel3"> <optionvalue="day">日</option> </select> <spanid="result"></span> </div></td></tr>
<tr><tdalign="right">我现在: </td> <td><selectname="subject"> <optionvalue="xu">正在上学</option> <optionvalue="cz">工作</option> <optionvalue="gz">赋闲</option> <optionvalue="bk">经商</option> </select></td></tr>
<tr><td></td><td>![](verycode.gif) <ahref="https://www.baidu.com">看不清换一张?</a> </td></tr> <tr><td>验证码:</td><td><inputtype="password"name="yanzheng"/></td></tr> <tr><td></td><td><ahref="https://www.baidu.com"> ![](btn_reg.gif)</a></td></tr> </table> </form> </body> </html> |
3.JavaScript代码
代码如下 | 复制代码 |
<script> //生成日期 functioncreatDate() { //生成1900年-2100年 for(vari = 2016; i >= 1950; i--) { //创建select项 varoption = document.createElement('option'); option.setAttribute('value',i); option.innerHTML = i; sel1.appendChild(option); } //生成1月-12月 for(vari = 1; i <=12; i++){ varoption1 = document.createElement('option'); option1.setAttribute('value',i); option1.innerHTML = i; sel2.appendChild(option1); } //生成1日—31日 for(vari = 1; i <=31; i++){ varoption2 = document.createElement('option'); option2.setAttribute('value',i); option2.innerHTML = i; sel3.appendChild(option2); } } creatDate(); //保存某年某月的天数 vardays;
//年份点击 绑定函数 sel1.onclick =function() { //月份显示默认值 sel2.options[0].selected =true; //天数显示默认值 sel3.options[0].selected =true; } //月份点击 绑定函数 sel2.onclick =function() { //天数显示默认值 sel3.options[0].selected =true; //计算天数的显示范围 //如果是2月 if(sel2.value == 2) { //判断闰年 if((sel1.value % 4 === 0 && sel1.value % 100 !== 0) || sel1.value % 400 === 0) { days = 29; } else { days = 28; } //判断小月 }elseif(sel2.value == 4 || sel2.value == 6 ||sel2.value == 9 ||sel2.value == 11){ days = 30; }else{ days = 31; }
//增加或删除天数 //如果是28天,则删除29、30、31天(即使他们不存在也不报错) if(days == 28){ sel3.remove(31); sel3.remove(30); sel3.remove(29); } //如果是29天 if(days == 29){ sel3.remove(31); sel3.remove(30); //如果第29天不存在,则添加第29天 if(!sel3.options[29]){ sel3.add(newOption('29','29'),null) } } //如果是30天 if(days == 30){ sel3.remove(31); //如果第29天不存在,则添加第29天 if(!sel3.options[29]){ sel3.add(newOption('29','29'),null) } //如果第30天不存在,则添加第30天 if(!sel3.options[30]){ sel3.add(newOption('30','30'),null) } } //如果是31天 if(days == 31){ //如果第29天不存在,则添加第29天 if(!sel3.options[29]) { sel3.add(newOption('29','29'),null) } //如果第30天不存在,则添加第30天 if(!sel3.options[30]) { sel3.add(newOption('30','30'),null) } //如果第31天不存在,则添加第31天 if(!sel3.options[31]) { sel3.add(newOption('31','31'),null) } } }
//结果显示 设置好日期时间后 弹窗通知 box.onclick =function() { //当年、月、日都已经为设置值时 if(sel1.value !='year'&& sel2.value !='month'&& sel3.value !='day') { alert("日期时间已经设定好"); } }
</script> |
相关文章
- 下面小编来给大家演示几个php操作zip文件的实例,我们可以读取zip包中指定文件与删除zip包中指定文件,下面来给大这介绍一下。 从zip压缩文件中提取文件 代...2016-11-25
Jupyter Notebook读取csv文件出现的问题及解决
这篇文章主要介绍了JupyterNotebook读取csv文件出现的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2023-01-06- 有时我们接受或下载到的PSD文件打开是空白的,那么我们要如何来解决这个 问题了,下面一聚教程小伙伴就为各位介绍Photoshop打开PSD文件空白解决办法。 1、如我们打开...2016-09-14
- 这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
- 这篇文章主要介绍了C#实现HTTP下载文件的方法,包括了HTTP通信的创建、本地文件的写入等,非常具有实用价值,需要的朋友可以参考下...2020-06-25
- 这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
- C#使用System.IO中的文件操作方法在Windows系统中处理本地文件相当顺手,这里我们还总结了在Oracle中保存文件的方法,嗯,接下来就来看看整理的C#操作本地文件及保存文件到数据库的基本方法总结...2020-06-25
php无刷新利用iframe实现页面无刷新上传文件(1/2)
利用form表单的target属性和iframe 一、上传文件的一个php教程方法。 该方法接受一个$file参数,该参数为从客户端获取的$_files变量,返回重新命名后的文件名,如果上传失...2016-11-25- 本文章来人大家介绍一个php文件上传类的使用方法,期望此实例对各位php入门者会有不小帮助哦。 简介 Class.upload.php是用于管理上传文件的php文件上传类, 它可以帮...2016-11-25
- 要替换字符串中的内容我们只要利用php相关函数,如strstr,str_replace,正则表达式了,那么我们要替换目录所有文件的内容就需要先遍历目录再打开文件再利用上面讲的函数替...2016-11-25
- 又码了一个周末的代码,这次在做一些关于文件上传的东西。(PHP UPLOAD)小有收获项目是一个BT种子列表,用户有权限上传自己的种子,然后配合BT TRACK服务器把种子的信息写出来...2016-11-25
- 本文实例讲述了jQuery实现文件上传进度条效果的代码。分享给大家供大家参考。具体如下: 运行效果截图如下:具体代码如下:<!DOCTYPE html><html><head><meta charset="utf-8"><title>upload</title><link rel="stylesheet...2015-11-24
- 今天小编在这里就来给photoshop的这一款软件的使用者们来说下AI源文件转photoshop图像变模糊问题的解决教程,各位想知道具体解决方法的使用者们,那么下面就快来跟着小编...2016-09-14
- 步骤:Window -> PHP -> Editor -> Templates,这里可以设置(增、删、改、导入等)管理你的模板。新建文件注释、函数注释、代码块等模板的实例新建模板,分别输入Name、Description、Patterna)文件注释Name: 3cfileDescriptio...2013-10-04
- 这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
- 本篇文章主要说明的是与php文件上传的相关配置的知识点。PHP文件上传功能配置主要涉及php.ini配置文件中的upload_tmp_dir、upload_max_filesize、post_max_size等选项,下面一一说明。打开php.ini配置文件找到File Upl...2015-10-21
ant design中upload组件上传大文件,显示进度条进度的实例
这篇文章主要介绍了ant design中upload组件上传大文件,显示进度条进度的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-10-29- 这篇文章主要介绍了C#使用StreamWriter写入文件的方法,涉及C#中StreamWriter类操作文件的相关技巧,需要的朋友可以参考下...2020-06-25
- 举一个案例:复制代码 代码如下:<?phpclass Downfile { function downserver($file_name){$file_path = "./img/".$file_name;//转码,文件名转为gb2312解决中文乱码$file_name = iconv("utf-8","gb2312",$file_name...2014-06-07
- 这篇文章主要介绍了C#路径,文件,目录及IO常见操作,较为详细的分析并汇总了C#关于路径,文件,目录及IO常见操作,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25