普通的html表单提交无法一次选择多文件上传,并且显示上传进度条比较麻烦。所以用flex做了一个多文件上传控件和大家分享
FileUpload.mxml
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" fontSize="12" creationComplete="init()"> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <fx:Script> <![CDATA[ import flash.events.*; import mx.collections.ArrayList; import mx.core.FlexGlobals; private var files : FileReferenceList; [Bindable] private var fileArray : ArrayList; private var serverUrl : String; private var userId : String; private var allowTypes : XML; private function init() : void { Security.allowDomain("*"); var params : Object = FlexGlobals.topLevelApplication.parameters; serverUrl = encodeURI(parameters.serverUrl); userId = params.userId; allowTypes = new XML( encodeURI(params.allowTypes) ); trace(userId); trace(serverUrl); trace(allowTypes.children()); files=new FileReferenceList(); files.addEventListener(Event.SELECT, onSelect); } private function upload() : void { var types : Array = new Array(); var typeXml : XMLList = allowTypes.children(); for(var i : int = 0; i < typeXml.length(); i++ ) { types.push( new FileFilter( typeXml[i].@name, typeXml[i].@pattern ) ); } files.browse(types); } private function onSelect(e:Event) : void { var request:URLRequest=new URLRequest(serverUrl); fileArray = new ArrayList(files.fileList); ExternalInterface.call("onFileSelect", fileArray.length); for(var i:int = 0; i < fileArray.length; i++) { var file:FileReference = fileArray.source[i] as FileReference; file.upload(request); } } ]]> </fx:Script> <s:VGroup> <s:Button label="上传文件" click="upload();" /> <s:List dataProvider="{fileArray}" itemRenderer="FileItem" borderVisible="false"/> </s:VGroup> </s:Application>
FileItem.mxml
<?xml version="1.0" encoding="utf-8"?> <s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" > <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <fx:Script> <![CDATA[ private var _data:Object; override public function set data( obj : Object ) : void { this._data = obj; var file : FileReference = (this._data as FileReference); file.addEventListener(ProgressEvent.PROGRESS, onProgress); file.addEventListener(Event.COMPLETE, onComplete); fileName.text = file.name; } override public function get data() : Object { return this._data; } private function onProgress(e:ProgressEvent) : void { cancelBtn.visible = true; var loaded : uint = e.bytesLoaded / 1024; var total : uint = e.bytesTotal / 1024; var proc:uint = e.bytesLoaded / e.bytesTotal * 100; bar.setProgress(proc, 100); bar.label = proc + "%"; labelProgress.text = loaded + "kb / " + total + "kb"; } private function onComplete(e:Event) : void { cancelBtn.visible = false; ExternalInterface.call("onUploadComplete"); } private function cancelUpload(e:Event) : void { var file : FileReference = (this._data as FileReference); file.cancel(); } ]]> </fx:Script> <s:states> <s:State name="normal"/> <s:State name="hovered"/> <s:State name="selected" /> </s:states> <s:layout> <s:VerticalLayout/> </s:layout> <s:HGroup verticalAlign="middle" paddingTop="5" paddingBottom="5"> <s:Label id="fileName"/> <mx:ProgressBar id="bar" labelPlacement="center" minimum="0" visible="true" maximum="100" label="0%" direction="right" mode="manual" width="200"/> <s:Label id="labelProgress" /> <s:Button id="cancelBtn" label="取消" click="cancelUpload(event)" visible="false" /> </s:HGroup> </s:ItemRenderer>
jsp引入部分
<script type="text/javascript" src="<c:url value="/assets/js/lib/upload/swfobject.js"/>"></script> <div style="height: 200px; width: 500px;"> <div id="flashContent"> <p> To view this page ensure that Adobe Flash Player version 10.0.0 or greater is installed. </p> <script type="text/javascript"> var pageHost = ((document.location.protocol == "https:") ? "https://" : "http://"); document.write("<a href='http://www.adobe.com/go/getflashplayer'><img src='" + pageHost + "www.adobe.com/images/shared/download_buttons/get_flash_player.gif' alt='Get Adobe Flash player' /></a>" ); </script> </div> </div> <script type="text/javascript"> <!-- For version detection, set to min. required Flash Player version, or 0 (or 0.0.0), for no version detection. --> var swfVersionStr = "10.0.0"; <!-- To use express install, set to playerProductInstall.swf, otherwise the empty string. --> var xiSwfUrlStr = "${contextPath}/assets/js/lib/upload/playerProductInstall.swf"; var flashvars = {}; flashvars.serverUrl = "${contextPath}/app/sys/file/upload;jsessionid=" + "<%= request.getSession().getId() %>"; flashvars.allowTypes = '<?xml version="1.0" encoding="UTF-8"?>' + '<allowTypes>' + '<type name="图像" pattern="*.jpg;*.jpeg;*.png;*.gif" />' + '<type name="文档" pattern="*.pdf;*.doc;*.txt" />' + '<type name="视频" pattern="*.avi;*.flv;*.rmvb" />' + '<type name="全部" pattern="*" />' + '</allowTypes>'; var params = {}; params.quality = "high"; params.bgcolor = "#ffffff"; params.allowscriptaccess = "sameDomain"; params.allowfullscreen = "true"; var attributes = {}; attributes.id = "FileUpload"; attributes.name = "FileUpload"; attributes.align = "middle"; swfobject.embedSWF( "${contextPath}/assets/js/lib/upload/FileUpload.swf", "flashContent", "100%", "100%", swfVersionStr, xiSwfUrlStr, flashvars, params, attributes); <!-- JavaScript enabled so display the flashContent div in case it is not replaced with a swf object. --> swfobject.createCSS("#flashContent", "display:block;text-align:left;"); var fileNum; function onFileSelect(num) { fileNum = num; } function onUploadComplete() { fileNum--; if(fileNum < 0) { showMsg("addRet", "文件上传成功!"); $grid.reload(); } } </script>
服务端接受文件代码
@RequestMapping(value = "/file/upload", method = RequestMethod.POST) public @ResponseBody String upload(HttpServletRequest request) { User user = (User) request.getSession().getAttribute( AuthenticationService.CURRENT_USER); Set<MultipartFile> mfs = getFileSet(request); for (MultipartFile mf : mfs) { String originalFilename = mf.getOriginalFilename(); String name = originalFilename.substring(0, originalFilename.lastIndexOf(".")).toLowerCase(); String extName = originalFilename.substring( originalFilename.lastIndexOf(".")).toLowerCase(); GenericFile file = new GenericFile(); file.setName(name); file.setExtName(extName); try { file.setFile(mf.getBytes()); } catch (IOException e) { e.printStackTrace(); } file.setUserId(user.getId()); file = fileService.save(file); log.info("save file {}", file.getId()); } int mfsSize = mfs.size(); log.info("file size {}", mfsSize); return mfsSize > 0 ? "true" : "false"; } private Set<MultipartFile> getFileSet(HttpServletRequest request) { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; Set<MultipartFile> fileset = new LinkedHashSet<MultipartFile>(); for (Iterator<String> it = multipartRequest.getFileNames(); it .hasNext();) { String key = it.next(); MultipartFile file = multipartRequest.getFile(key); if (file.getOriginalFilename().length() > 0) { log.info("file name [{}]", file.getOriginalFilename()); fileset.add(file); } } return fileset; }