利用jsp+uploadify插件实现附件上传到ftp服务器的功能
这个周中午闲暇的时候研究了一下uploadify插件的使用,主要是想要实现一个附件上传的功能,看之前公司同事好像用过这个插件,但是见人家挺忙的,我只能找到她写的自己研究了,好来,话不多说,先把实现的效果贴出来给大家看看:
这是还未点击上传附件的界面(图:1)
当点击选择附件界面会弹出文件选择对话框如下:
选择好要上传的文件点击打开按钮,文件开始上传:
上传完成之后界面如下(上传进度条消失):
**由上面的效果图可以看出我做的这个附件上传整体效果是:
点击附件上传按钮–>选择要上传的文件–>上传文件—>显示上传文件的文件列表**
(一)、下载uploadify插件
uploadify是jquery的一个上传插件,实现的效果非常不错,带进度显示。不过官方提供的实例时php版本的,下面我用jsp+servlet简单实现了这个功能,你可以通过下面我分享的连接下载uoploadify文件:
下载jsp版本uploadify(我自己使用的文件)
(二)、下载插件安装包后,可以看到里面文件夹的几个主要文件:
(1)jquery.uploadify.js:完成上传功能的脚本文件,在调用页面引用(上传插件)
(2)uploadify.css:上传控件样式表,外观样式表
(3)uploader.swf:上传控件的主体文件,flash控件
(4)jquery.uploadify.min.js:压缩版的上传插件,部署时使用
(三)、项目环境介绍
我是在myeclipse下创建的java web的maven项目,搭建了springmvc的框架
说到这里我们需要的uploadify插件和运行环境就准备好了,我想很多人和我一样在最开始肯定会想到我们平时上传附件的时候一些场景,比如说我们上传资料到百度云盘时候的过程ps:如果想不起来可以自己去百度云盘上传文件体验一次,哈哈,可能不同的的人在思考上传附件这个功能的实现的时候会有不同的问题或者想法,就我来说我当时其实最好奇的是上传的附件到底最后是上传到了哪里,如果是上传到自己本地,肯定第不可能的,因为这样的话换台电脑找不到对应的位置上传肯定就会出问题,我想这个存放文件的地方一定是不管在哪里都可以访问的到的,因为文件上传了必然会存在一个文件下载的过程,我们在访问网页的时候会看到有很多地址链接,你一点击就会把相应的文件下载下来,这背后肯定就会有一个地址是我们下载对应文件的路径,知道了路径我们才能下载,但是想到这里我还是不知道要怎么做,不知道笔者们有没有人也思考过这个问题,因为我对java算是新手入门,项目经验很浅,对我来说这还真的算是个小白,怀着疑问我又赶紧上网查资料,可是却没有找到我觉得有价值的信息,郁闷了好一会儿,突然想起来我手上还有源码呢,赶快去里面找找有没有什么线索,果然皇天不负有心人,我发现了一个在src/main/resources/目录下有一个名叫:ftpconfig.properties的文件,我顺着这个文件继续钻,发现同事是把上传的附件存放在ftp服务器上面的,然后百度了ftp服务器的相关资料惊喜的发现了:原来我们可以创建一个远程ftp服务器,然后在连接ftp服务器,在登陆ftp服务器,登陆成功就可以将文件上到这个服务器,关于ftp服务器相关的资料童鞋们可以自己问问度娘,哈哈,一般来说公司有上传文件需求的都会创建自己的ftp服务器供大家使用,总之如果你要在项目中要连接ftp服务器你需要实现一下步骤:
(1)、ftpconfig.properties文件配置一些ftp服务器中的参数信息:
(2) 在readiniinfo类中对ftp.properties的加载处理,并初始化ftp连接,并建立连接
readiniinfo.java:
/** * * @描述: 读取配置文件 */ public class readiniinfo { private inputstream is; private properties properties; //初始化配置文件 public readiniinfo() { properties = new properties(); //读取配置文件:ftpconfig.properties is = this.getclass().getresourceasstream("/ftpconfig.properties"); try { properties.load(is); } catch (filenotfoundexception e) { system.out.println("配置文件不存在.."); e.printstacktrace(); } catch (ioexception e) { system.out.println("读取配置文件错误:" + e.getmessage()); e.printstacktrace(); } finally { try { if (null != is) { is.close(); } } catch (ioexception e) { system.out.println("关闭链接失败.."); e.printstacktrace(); } } } /** * 获取ftp服务器地址 */ public string getftpserver() { return properties.getproperty("ftpserver"); } /** * 获取ftp服务器端口 */ public string getftpport() { return properties.getproperty("ftpport"); } /** * 获取ftp用户账号 */ public string getftpuser() { return properties.getproperty("ftpuser"); } /** * 获取ftp用户密码 */ public string getftppwd() { return properties.getproperty("ftppwd"); } /** * 获取ftp目的地仓库地址 */ public string getftpremotepath() { return properties.getproperty("ftpremotepath"); } /** * http和ftp上传时的固定路径部份 */ public string getpathconstant() { return properties.getproperty("pathconstant"); } /** * 图片资源管理图片路径 */ public string getimagecenter() { return properties.getproperty("imagecenter"); } /** * 压缩图 */ public string getcompress() { return properties.getproperty("compress"); } /** * 公文管理的附件路径 */ public string getgwgl() { return properties.getproperty("gwgl"); } }
(4) 定义ftp接口类,提供登陆等相关接口,用于登陆ftp服务器
/** * @描述: ftp接口类 */ public interface ftpservice { /** * 登陆ftp服务器 */ public void login(ftpclient ftpclient, readiniinfo iniinfo) throws exception; /** * 断开服务器链接 */ public void logout(ftpclient ftpclient) throws exception; /** * 上传本地文件 */ public void uploadfile(ftpclient ftpclient, string remotepath, string filenewname, inputstream inputstream, readiniinfo iniinfo) throws exception; /** * 远程文件列表 */ public list> listfile(ftpclient ftpclient, string remotepath) throws exception; /** * 下载远程文件 */ public inputstream downfilebyftp(ftpclient ftpclient, string remotepath, string filename) throws exception; /** * * @描述:删除文件 */ public void delfile(ftpclient ftpclient, string pathname) throws exception; }
ftp各个接口的具体实现:
/** * @描述: ftp接口实例类 */ @service public class ftpserviceimpl implements ftpservice { /** * 登陆ftp服务器 */ public void login(ftpclient ftpclient, readiniinfo iniinfo) throws exception { //获取ftp服务器地址 string ftpserver = iniinfo.getftpserver(); //获取ftp服务器端口 string ftpport = iniinfo.getftpport(); //获取ftp用户账号 string ftpuser = iniinfo.getftpuser(); //获取ftp用户密码 string ftppwd = iniinfo.getftppwd(); try { // 链接到ftp服务器 ftpclient.connect(ftpserver, integer.valueof(ftpport)); system.out.println("链接到ftp服务器:" + ftpserver + "成功.."); // 开始登陆服务器 boolean boo = ftpclient.login(ftpuser, ftppwd); if (boo) { system.out.println("登陆到ftp服务器:" + ftpserver + "成功.."); } else { system.out.println("登陆到ftp服务器:" + ftpserver + "失败.."); logout(ftpclient);//退出/断开ftp服务器链接 } } catch (exception e) { e.printstacktrace(); system.err.println("登陆到ftp服务器:" + ftpserver + "失败.."); } } /** * 上传本地文件 * @param filenewname 文件更改后的名称 * @throws exception */ public void uploadfile(ftpclient ftpclient, string pathconstant, string filenewname, inputstream inputstream, readiniinfo iniinfo) throws exception { try { string ftpremotepath = iniinfo.getftpremotepath();//ftp目的地仓库位置,而文件实例地址=仓库位置+上传指定位置 //设置被动模式 // 设置passivemode传输 ftpclient.enterlocalpassivemode(); // 设置以二进制流的方式传输 ftpclient.setfiletype(ftp.binary_file_type); //设置字符集 ftpclient.setcontrolencoding("gbk"); //创建目录结构 if (pathconstant != null && !"".equals(pathconstant.trim())) { string[] pathes = pathconstant.split("/"); for (string onepath : pathes) { if (onepath == null || "".equals(onepath.trim())) { continue; } onepath = new string(onepath.getbytes("gbk"), "iso-8859-1"); if (!ftpclient.changeworkingdirectory(onepath)) { ftpclient.makedirectory(onepath);//创建ftp服务器目录 ftpclient.changeworkingdirectory(onepath);//改变ftp服务器目录 } } } boolean boo = ftpclient.storefile(new string(filenewname.getbytes("gbk"), "iso-8859-1"), inputstream); if (boo) { system.out.println("文件上传成功.."); } else { system.out.println("文件上传失败.."); } } catch (exception e) { e.printstacktrace(); } finally { try { if (null != inputstream) { inputstream.close(); } logout(ftpclient);//退出/断开ftp服务器链接 } catch (ioexception e) { system.out.println("关闭链接失败.."); e.printstacktrace(); } } } /** * 远程文件列表 */ public list> listfile(ftpclient ftpclient, string remotepath) throws exception { //设置目录字符集 string remp = new string(remotepath.getbytes("gbk"), "iso-8859-1"); ftplistparseengine engine = ftpclient.initiatelistparsing(remotepath); list remotefiles = arrays.aslist(engine.getnext(25)); list> list = new arraylist>(); if (remotefiles != null && remotefiles.size() != 0) { system.out.println("目录" + remotepath + "下的文件列表.."); } else { system.out.println("目录" + remotepath + "下无文件内容.."); } //递归目录文件 for (ftpfile ftpfile : remotefiles) { map map = new hashmap(); map.put("filename", ftpfile.getname());//文件名称 map.put("filesize", long.tostring(ftpfile.getsize()));//文件大小 //文件时间 map.put("filetime", new simpledateformat("yyyy/mm/dd kk:mm:ss").format(ftpfile.gettimestamp().gettime())); list.add(map); } logout(ftpclient);//退出/断开ftp服务器链接 return list; } public inputstream downfilebyftp(ftpclient ftpclient, string remotepath, string filename) throws exception { ftpfile[] fs; inputstream is = null; try { //设置被动模式 ftpclient.enterlocalpassivemode(); // 设置以二进制流的方式传输 ftpclient.setfiletype(ftp.binary_file_type); //设置编辑格式 ftpclient.setcontrolencoding("gbk"); remotepath = remotepath.substring(0, remotepath.lastindexof(filename)); fs = ftpclient.listfiles(remotepath);//递归目标目录 for (ftpfile ff : fs) { if (ff.getname().equals(filename)) {//查找目标文件 is = ftpclient .retrievefilestream(new string((remotepath + filename).getbytes("gbk"), "iso-8859-1")); break; } } } catch (ioexception e) { e.printstacktrace(); } return is; } /** * 退出/断开ftp服务器链接 */ public void logout(ftpclient ftpclient) throws exception { ftpclient.logout();//退出登陆 system.out.println("已退出ftp远程服务器.."); if (ftpclient.isconnected()) { ftpclient.disconnect();//断开链接 system.out.println("已断开ftp服务器链接.."); } } /** * * @描述:删除文件 */ public void delfile(ftpclient ftpclient, string pathname) throws exception { try { boolean boo = ftpclient.deletefile(pathname); if (boo) { system.out.println("文件删除成功.."); } else { system.out.println("文件删除失败.."); } } catch (exception e) { e.printstacktrace(); } finally { //logout(ftpclient);//退出/断开ftp服务器链接 } } }
以上主要是主要完成两件事:
1、下载uploadify插件
2、tp服务器的相关需要的类和配置文件
现在真正开始实现上传文件的过程:
(四)、实现步骤:
(4.1)、创建uploadify.jsp文件
(4.2)、在uploadify.jsp文件引入uploadify插件相关的文件
(4.3)上传附件界面(uploadify.jsp的部分)
(4.4)前台编码(uploadify.jsp的部分)
初始化uploadify插件
可能截图有些看不清楚:小主也没有办法
大家如果想看uploadify.jsp源码的话点这里下载噢
(4.5)后台处理前台发过来的请求上传的请求
@controller @requestmapping(value="uploadify") public class uploadifycontroller { @autowired private ftpservice ftpservice ; private static string ftp_root_path = "document_manage"; /** * * @功能描述 附件上传 */ @requestmapping(value = "/upload.action") public void upload(httpservletrequest request, httpservletresponse response) { jsonobject result = new jsonobject(); try { //创建一个通用的多部分解析器 commonsmultipartresolver multipartresolver = new commonsmultipartresolver(request.getsession().getservletcontext()); //判断 request 是否有文件上传,即多部分请求 if (multipartresolver.ismultipart(request)) { //转换成多部分request multiparthttpservletrequest multirequest = (multiparthttpservletrequest)multipartresolver.resolvemultipart(request); //取得request中的所有文件名 iterator iter = multirequest.getfilenames(); //登陆ftp readiniinfo iniinfo = new readiniinfo(); ftpclient ftpclient = new ftpclient(); ftpservice.login(ftpclient, iniinfo); jsonarray upresult = new jsonarray(); while (iter.hasnext()) { //取得上传文件 multipartfile file = multirequest.getfile(iter.next()); if (file != null) { //当前上传文件的文件名称 string filename = file.getoriginalfilename(); //当前上传文件的文件类型 //string filetype = file.getcontenttype(); //当前上传文件的文件大小 long filesize = file.getsize(); //当前上传文件的文件后缀 string suffix = filename.indexof(".") != -1 ? filename.substring(filename.lastindexof("."), filename.length()) : null; //如果名称不为“”,说明该文件存在,否则说明该文件不存在 if (!stringutils.isblank(filename)) { //创建文件对象 tbdocumentfile myfile=new tbdocumentfile(); //重命名上传后的文件名 string savefilename = identities.uuid2() + suffix; //定义上传路径 string savepath = ftp_root_path + "/" + dateutils.format("yyyymmdd", new date()) + "/"; //当前上传文件信息 jsonobject fileinfo = new jsonobject(); fileinfo.put("fileoriginalname", filename); fileinfo.put("filename", savefilename); fileinfo.put("filesize", filesize); fileinfo.put("filesuffix", suffix); fileinfo.put("filepath", savepath); fileinfo.put("id", identities.uuid()); try { ftpservice.uploadfile(ftpclient, savepath, savefilename, file.getinputstream(), iniinfo); fileinfo.put("success", true); } catch (exception e) { e.printstacktrace(); fileinfo.put("success", false); fileinfo.put("msg", "系统异常,上传失败!"); fileinfo.put("exception", e.getmessage()); } upresult.add(fileinfo); } } } result.put("upresult", upresult); } result.put("success", true); result.put("msg", "上传成功!"); } catch (exception e) { e.printstacktrace(); result.put("success", false); result.put("msg", "系统异常,上传失败!"); result.put("exception", e.getmessage()); } responseutils.renderjson(response, result.tostring(), "encoding:utf-8"); } }
至此上传附件到ftp服务器成功,在这里我着重想要总结一下我在实现的过程中遇到的问题,主要是关于当上传成功之后显示上传成功的文件列表这个部分:
//itemtemplate是uploadify插件的一个参数是用来设置上传队列的html模板的,我们可以自己定义想要显示的模板 var itemhtml = itemtemplate; for ( var d in itemdata) { //d表示itemdata的每个属性(如:filedid、filename等),itemdata[d]表示相应属性(filedid)对应的值 //new regexp()是正则表达式 itemhtml = itemhtml.replace(new regexp( '\\{' + d + '\\}', 'g'), itemdata[d]); }
下面截图就是alert(itemhtml)显示的内容:
累死宝宝了,先写到这里了。
下一篇: JSP的图形验证码 -汉字