webuploader实现附件分片上传并列举一下遇到的问题和解决办法

1.前端代码:
js代码:

/**
 * webloader文件上传器
 *
 * @reference http://fex.baidu.com/webuploader/
 * @author [email protected] create
 * @author [email protected] modify
 */
(function ($) {
	function getUrlParam(name) {
	    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
	    var r = window.location.search.substr(1).match(reg);  //匹配目标参数
	    if (r != null) return unescape(r[2]); return null; //返回参数值
	}
	var callBackFunId = getUrlParam('callBackFunId');//返回参数
	var rootFileType = getUrlParam('rootFileType');//文件类型1标示文件2表示图片 
	var rootObjId = window.parent.rootObjId;        //业务单id
	//var rootFileType = rootFileType;  //文件类型:1 文件;2图片
    // 当domReady的时候开始初始化
    $(function () {
        var $wrap = $('#uploader'),
        // 图片容器
            $queue = $('
    ') .appendTo($wrap.find('.queueList')), // 状态栏,包括进度和控制按钮 $statusBar = $wrap.find('.statusBar'), // 文件总体选择信息。 $info = $statusBar.find('.info'), // 上传按钮 $upload = $wrap.find('.uploadBtn'), // 没选择文件之前的内容。 $placeHolder = $wrap.find('.placeholder'), $progress = $statusBar.find('.progress').hide(), // 添加的文件数量 fileCount = 0, // 添加的文件总大小 fileSize = 0, // 优化retina, 在retina下这个值是2 ratio = window.devicePixelRatio || 1, // 缩略图大小 thumbnailWidth = 110 * ratio, thumbnailHeight = 110 * ratio, // 可能有pedding, ready, uploading, confirm, done. state = 'pedding', // 所有文件的进度信息,key为file id percentages = {}, // 判断浏览器是否支持图片的base64 isSupportBase64 = (function () { var data = new Image(); var support = true; data.onload = data.onerror = function () { if (this.width != 1 || this.height != 1) { support = false; } }; data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; return support; })(), // 检测是否已经安装flash,检测flash的版本 flashVersion = (function () { var version; try { version = navigator.plugins['Shockwave Flash']; version = version.description; } catch (ex) { try { version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash') .GetVariable('$version'); } catch (ex2) { version = '0.0'; } } version = version.match(/\d+/g); return parseFloat(version[0] + '.' + version[1], 10); })(), supportTransition = (function () { var s = document.createElement('p').style, r = 'transition' in s || 'WebkitTransition' in s || 'MozTransition' in s || 'msTransition' in s || 'OTransition' in s; s = null; return r; })(), // WebUploader实例 uploader; if (!WebUploader.Uploader.support('flash') && WebUploader.browser.ie) { // flash 安装了但是版本过低。 if (flashVersion) { (function (container) { window['expressinstallcallback'] = function (state) { switch (state) { case 'Download.Cancelled': cui.alert("您取消了更新!"); break; case 'Download.Failed': cui.alert('安装失败'); break; default: cui.alert('安装已成功,请刷新!'); break; } delete window['expressinstallcallback']; }; var swf = './expressInstall.swf'; // insert flash object var html = '' + '' + '' + ''; container.html(html); })($wrap); // 压根就没有安转。 } else { $wrap.html('get flash player'); } return; } else if (!WebUploader.Uploader.support()) { cui.alert('Web Uploader 不支持您的浏览器!'); return; } var serverUrl = "/api/pmpro-base/attachmentUpload/upload"; //后台url var fileVal = "attachmentFile"; var jobTypeCode = "attachment"; var objectId = "attachmentTest"; //设置可上传文件类型 var acceptType = { title: 'Images', extensions: 'doc,docx,pdf,ppt,pptx,jpg,gif,bmp,png,zip,xls,xlsx', mimeTypes: 'application/msword,' + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,' + 'application/pdf,' + 'application/vnd.ms-powerpoint,' + "application/vnd.openxmlformats-officedocument.presentationml.presentation pptx,"+ "image/jpg,"+ "image/gif,"+ "image/bmp,"+ 'image/png,'+ "application/zip,"+ "application/vnd.ms-excel,"+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }; //组件可接受文件类型 // 实例化 uploader = WebUploader.create({ threads: 1, //上传并发数。允许同时最大上传进程数。 pick: { id: '#filePicker', innerHTML: '添加附件' }, formData: { //@必填,参数设置,这里必须设置你的业务ID,附件上传功能必须关联业务ID,必须唯一。 jobTypeCode:jobTypeCode, objectId:objectId }, fileVal: fileVal, //@可选,参数设置,设置文件上传域的name,即后台请求参数。默认为"file"。 dnd: '#dndArea', //指定Drag And Drop拖拽的容器,如果不指定,则不启动 paste: '#uploader', //指定监听paste事件的容器,如果不指定,不启用此功能。此功能为通过粘贴来添加截屏的图片 swf: '../../dist/Uploader.swf', chunked: true, //是否开启大文件分片上传 chunkSize: 500 * 1024, //如果开启分片,设置每片大小为500K. server: serverUrl, //服务端文件接收地址 // runtimeOrder: 'flash', //设置可选文件类型,如果不设置,默认为null,似乎~可以上传任意文件。 accept:acceptType, // 禁掉全局的拖拽功能。这样不会出现图片拖进页面的时候,把图片打开。 disableGlobalDnd: true, fileNumLimit: 10, //最多一次10个文件 fileSizeLimit: 2000 * 1024 * 1024, // 总大小2000 M fileSingleSizeLimit: 200 * 1024 * 1024 // 单个大小 200M }); // 拖拽时不接受 js, txt 文件。 uploader.on('dndAccept', function (items) { var denied = false, len = items.length, i = 0, // 修改js类型 unAllowed = 'text/plain;application/javascript '; for (; i < len; i++) { // 如果在列表里面 if (~unAllowed.indexOf(items[i].type)) { denied = true; break; } } return !denied; }); uploader.on('dialogOpen', function () { //console.log('打开选择文件窗口'); }); // 添加“添加文件”的按钮, uploader.addButton({ id: '#filePicker2', label: '继续添加' }); uploader.on('ready', function () { window.uploader = uploader; }); // 当有文件添加进来时执行,负责view的创建 function addFile(file) { var $li = $('
  • ' + '

    ' + file.name + '

    ' + '

    ' + '

    ' + '
  • '), $btns = $('
    ' + '删除' + '向右旋转' + '向左旋转
    ').appendTo($li), $prgress = $li.find('p.progress span'), $wrap = $li.find('p.imgWrap'), $info = $('

    '), showError = function (code) { switch (code) { case 'exceed_size': text = '文件大小超出'; break; case 'interrupt': text = '上传暂停'; break; default: text = '上传失败,请重试'; break; } $info.text(text).appendTo($li); }; if (file.getStatus() === 'invalid') { showError(file.statusText); } else { // @todo lazyload $wrap.text('预览中'); uploader.makeThumb(file, function (error, src) { var img; if (error) { $wrap.text('不能预览'); return; } if (isSupportBase64) { img = $(''); $wrap.empty().append(img); } else { $.ajax('../../server/preview.php', { method: 'POST', data: src, dataType: 'json' }).done(function (response) { if (response.result) { img = $(''); $wrap.empty().append(img); } else { $wrap.text("预览出错"); } }); } }, thumbnailWidth, thumbnailHeight); percentages[file.id] = [file.size, 0]; file.rotation = 0; } file.on('statuschange', function (cur, prev) { if (prev === 'progress') { $prgress.hide().width(0); } else if (prev === 'queued') { $li.off('mouseenter mouseleave'); $btns.remove(); } // 成功 if (cur === 'error' || cur === 'invalid') { console.log(file.statusText); showError(file.statusText); percentages[file.id][1] = 1; } else if (cur === 'interrupt') { showError('interrupt'); } else if (cur === 'queued') { $info.remove(); $prgress.css('display', 'block'); percentages[file.id][1] = 0; } else if (cur === 'progress') { $info.remove(); $prgress.css('display', 'block'); } else if (cur === 'complete') { $prgress.hide().width(0); $li.append(''); } $li.removeClass('state-' + prev).addClass('state-' + cur); }); $li.on('mouseenter', function () { $btns.stop().animate({height: 30}); }); $li.on('mouseleave', function () { $btns.stop().animate({height: 0}); }); $btns.on('click', 'span', function () { var index = $(this).index(), deg; switch (index) { case 0: uploader.removeFile(file); return; case 1: file.rotation += 90; break; case 2: file.rotation -= 90; break; } if (supportTransition) { deg = 'rotate(' + file.rotation + 'deg)'; $wrap.css({ '-webkit-transform': deg, '-mos-transform': deg, '-o-transform': deg, 'transform': deg }); } else { $wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')'); } }); $li.appendTo($queue); } // 负责view的销毁 function removeFile(file) { var $li = $('#' + file.id); delete percentages[file.id]; updateTotalProgress(); $li.off().find('.file-panel').off().end().remove(); } function updateTotalProgress() { var loaded = 0, total = 0, spans = $progress.children(), percent; $.each(percentages, function (k, v) { total += v[0]; loaded += v[0] * v[1]; }); percent = total ? loaded / total : 0; spans.eq(0).text(Math.round(percent * 100) + '%'); spans.eq(1).css('width', Math.round(percent * 100) + '%'); updateStatus(); } function updateStatus() { var text = '', stats; if (state === 'ready') { text = '选中' + fileCount + '个文件,共' + WebUploader.formatSize(fileSize) + '。'; } else if (state === 'confirm') { stats = uploader.getStats(); if (stats.uploadFailNum) { text = '已成功上传' + stats.successNum + '个文件,' + stats.uploadFailNum + '个文件上传失败,重新上传失败文件或忽略' } } else { stats = uploader.getStats(); text = '共' + fileCount + '张(' + WebUploader.formatSize(fileSize) + '),已上传' + stats.successNum + '张'; if (stats.uploadFailNum) { text += ',失败' + stats.uploadFailNum + '张'; } } $info.html(text); //调用父页面方法,更新列表 // window.parent.loadPage(); } //设置状态 function setState(val) { var file, stats; if (val === state) { return; } $upload.removeClass('state-' + state); $upload.addClass('state-' + val); state = val; switch (state) { case 'pedding': $placeHolder.removeClass('element-invisible'); $queue.hide(); $statusBar.addClass('element-invisible'); uploader.refresh(); break; case 'ready': $placeHolder.addClass('element-invisible'); $('#filePicker2').removeClass('element-invisible'); $queue.show(); $statusBar.removeClass('element-invisible'); uploader.refresh(); break; case 'uploading': $('#filePicker2').addClass('element-invisible'); $progress.show(); $upload.text('暂停上传'); break; case 'paused': $progress.show(); $upload.text('继续上传'); break; case 'confirm': $progress.hide(); $('#filePicker2').removeClass('element-invisible'); $upload.text('开始上传'); stats = uploader.getStats(); if (stats.successNum && !stats.uploadFailNum) { setState('finish'); return; } break; case 'finish': stats = uploader.getStats(); if (stats.successNum) { //调用父页面方法,更新列表 window.parent.loadPage(); cui.message('上传成功', 'success'); if(uploadFlag == 0){ //模型列表页面上传 window.parent.docsFileGridInitData(localStorage.getItem("documentTypeId")); } else if(uploadFlag == 1){ //文档智能管理页面上传 window.parent.recordGridInit(localStorage.getItem("ai_documentTypeId")); } } else { // 没有成功的图片,重设 state = 'done'; location.reload(); } break; } updateStatus(); } uploader.onUploadProgress = function (file, percentage) { var $li = $('#' + file.id), $percent = $li.find('.progress span'); $percent.css('width', percentage * 100 + '%'); percentages[file.id][1] = percentage; updateTotalProgress(); }; var md5Value; //添加文件后的事件委托 uploader.onFileQueued = function (file) { //计算md5 uploader.md5File( file ) // 完成 .then(function(md5) { md5Value =md5; console.log("md5Value----" + md5); }); fileCount++; fileSize += file.size; if (fileCount === 1) { $placeHolder.addClass('element-invisible'); $statusBar.show(); } addFile(file); setState('ready'); updateTotalProgress(); }; //删除文件后的事件委托 uploader.onFileDequeued = function (file) { fileCount--; fileSize -= file.size; if (!fileCount) { setState('pedding'); } removeFile(file); updateTotalProgress(); }; //监听每一步骤的事件 uploader.on('all', function (type) { var stats; switch (type) { case 'uploadFinished': setState('confirm'); break; case 'startUpload': setState('uploading'); break; case 'stopUpload': setState('paused'); break; } }); //处理全局错误 uploader.onError = function (code) { console.log(code); if(code='Q_EXCEED_NUM_LIMIT'){ cui.alert('提示:上传文件数量超出限制'); }else if(code='Q_EXCEED_SIZE_LIMIT'){ cui.alert('提示:上传文件大小超出限制'); }else if(code='Q_TYPE_DENIED'){ cui.alert('提示:上传文件类型未定义'); }else{ cui.message('提示:' + code, 'alert'); } }; //点击上传时候的动作 $upload.on('click', function () { if ($(this).hasClass('disabled')) { return false; } if (state === 'ready') { uploader.upload(); } else if (state === 'paused') { uploader.upload(); } else if (state === 'uploading') { uploader.stop(); } }); //当上传失败之后,点击重试 $info.on('click', '.retry', function () { uploader.retry(); }); //当上传失败之后,点击忽略 $info.on('click', '.ignore', function () { for (var i = 0; i < uploader.getFiles("error").length; i++) { uploader.removeFile(uploader.getFiles("error")[i]); // 将图片从缩略图容器移除 var $li = $('#' + uploader.getFiles("error")[i].id); $li.off().remove(); } }); $upload.addClass('state-' + state); updateTotalProgress(); }); })(jQuery);

    (2)后端代码:

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.SequenceInputStream;
    import java.net.MalformedURLException;
    import java.net.URLEncoder;
    import java.util.Enumeration;
    import java.util.List;
    import java.util.Vector;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.junit.Test;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    
    import com.caucho.hessian.client.HessianProxyFactory;
    import ***.ResultVO;
    import ***.util.ATMUtil;
    import ***.util.FileUtil;
    import ***.model.AttachmentTransVO;
    
    /**
     * 附件上传Controller
     * @history jdk1.87
     */
    @Controller
    @RequestMapping("/attachmentUpload")
    public class AttachmentUploadController {
    	private static Logger LOG = LoggerFactory.getLogger(AttachmentUploadController.class);
    	private static final int SUCCESS = 1;
    	private static final int ERROR = 0;
       //合并分片的文件,因为每个片都是一次请求,所以合并分片的容器只创建一次
    	private static Vector v;
    	static {
    		v = new Vector();
    	}
    
    	/**
    	 * 文件上传
    	 * 
    	 * @param file
    	 *            文件对象
    	 * @param documentTypeId
    	 *            文件类型id
    	 * @return
    	 */
    	@RequestMapping(value = "/upload")
    	@ResponseBody
    	public String upload(@RequestParam("attachmentFile") MultipartFile file, @RequestParam("objectId") String objectId,
    			@RequestParam("jobTypeCode") String jobTypeCode, HttpServletRequest request, HttpServletResponse response,
    			String chunks, String chunk, String md5Value) {
    		String fileName = file.getOriginalFilename();
    		// 创建AttachmentTransVO对象
    		AttachmentTransVO objAttachmentVO = new AttachmentTransVO();
    		objAttachmentVO.setJobTypeCode(jobTypeCode);
    		objAttachmentVO.setObjectId(objectId);
    		objAttachmentVO.setCreatorId("SuperAdmin");
    		objAttachmentVO.setCreatorName("SuperAdmin");
    		objAttachmentVO.setFileName(fileName);
    		String FileExt = fileName.substring(fileName.lastIndexOf(".") + 1);
    		objAttachmentVO.setFileType(FileExt.toLowerCase());
    
    		SequenceInputStream sequenceInputStream = null;
    		FileOutputStream fos = null;
    		InputStream inputStream = null;
    		try {
    			// 判断是否分片
    			if (chunks != null && chunk != null) {
    				// 创建临时目录,保存每个分片文件
    				String fileUrl = ATMUtil.saveChunk(file, chunk);
    
    				// 合并分片文件并上传
    				if (Integer.valueOf(chunk) == (Integer.valueOf(chunks) - 1)) {
    					v.add(new FileInputStream(fileUrl));
    					Enumeration en = v.elements();
    					sequenceInputStream = new SequenceInputStream(en);
    					// 保存合并的文件到本地
    					fos = new FileOutputStream(ATMUtil.getATM_TEMPDIR() + fileName);
    					byte[] buf = new byte[1024 * 1024];
    					int len = 0;
    					while ((len = sequenceInputStream.read(buf)) != -1) {
    						fos.write(buf, 0, len);
    						fos.flush();//这里最好也注意要有
    					}
    					
    					inputStream = new FileInputStream(ATMUtil.getATM_TEMPDIR() + fileName);
    					objAttachmentVO.setFileSize(inputStream.available());
    					LOG.info("合并分片后的字节数:" + inputStream.available());
    					// 上传文件到ATM
    					AttachmentTransVO resultAttachment = ATMUtil.uploadAttachment(objAttachmentVO, inputStream);
    					// 清空Vector,关闭流
    					v.clear();//这里必须注意,当初忘记写这个被坑的好惨
    					sequenceInputStream.close();
    					fos.close();
    					inputStream.close();
    					
    				} else {
    					v.add(new FileInputStream(fileUrl));
    				}
    			} else {
    				// 没有分片
    				inputStream = file.getInputStream();
    				objAttachmentVO.setFileSize(inputStream.available());
    				AttachmentTransVO resultAttachment = ATMUtil.uploadAttachment(objAttachmentVO, inputStream);
    				inputStream.close();
    			}
    			// 删除临时文件
    			//FileUtil.delFolder(ATMUtil.getATM_ROOTDIR());
    		} catch (Exception e) {
    			LOG.error("分片上传出错", e);
    			// return RETURN.fail("分片上传出错", 1);
    		} 
    		return null;
    	}
    
    	/**
    	 * 获取文件列表
    	 * 
    	 * @param jobTypeCode
    	 * @param objectId
    	 * @return 存储文件信息的对象集合
    	 */
    	@RequestMapping("/getList")
    	@ResponseBody
    	public ResultVO getList(@RequestParam String jobTypeCode, @RequestParam String objectId) {
    		ResultVO objResult = new ResultVO();
    		List listAttachment = null;
    		HessianProxyFactory factory = new HessianProxyFactory();
    		ILcamAttachmentProcess hessianServer;
    		try {
    			hessianServer = (ILcamAttachmentProcess) factory.create(ILcamAttachmentProcess.class, ATMUtil.getATM_URL());
    			// 获取指定业务单下所有的附件
    			listAttachment = hessianServer.getAttchmentByObjId("attachment", "attachmentTest");
    		} catch (Exception e) {
    			e.printStackTrace();
    			LOG.error("查询附件列表出错");
    		}
    		if (listAttachment != null) {
    			objResult.setResultState(SUCCESS);
    			objResult.setResultData(listAttachment);
    		} else {
    			objResult.setResultState(ERROR);
    		}
    		return objResult;
    	}
    
    	/**
    	 * 根据附件id下载附件
    	 * 
    	 * @param attachmentId
    	 *            附件id
    	 * @param request
    	 * @param response
    	 */
    	@RequestMapping("/download/{attachmentId}")
    	@ResponseBody
    	public void download(@PathVariable String attachmentId, HttpServletRequest request, HttpServletResponse response) {
    		AttachmentTransVO objAttachmentVO = null;
    		HessianProxyFactory factory = new HessianProxyFactory();
    		ILcamAttachmentProcess hessianServer;
    		try {
    			hessianServer = (ILcamAttachmentProcess) factory.create(ILcamAttachmentProcess.class, ATMUtil.getATM_URL());
    			// 根据attachmentId获取文件信息
    			objAttachmentVO = hessianServer.getAttachmentInfo(attachmentId);
    			String fileName = objAttachmentVO.getFileName();
    			fileName = URLEncoder.encode(fileName, "UTF-8");
    
    			// 根据attachmentId获取文件字节流
    			byte[] buffer = hessianServer.downloadAttachment(attachmentId);
    			response.setContentType("application/force-download");// 设置强制下载不打开
    			response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
    			OutputStream os = response.getOutputStream();
    			os.write(buffer);
    
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    	}
    
    	@RequestMapping("/deleteAttachment/{jobTypeCode}/{objectId}/{attachmentIds}")
    	@ResponseBody
    	public ResultVO deleteAttachment(@PathVariable String jobTypeCode, @PathVariable String objectId,
    			@PathVariable String attachmentIds, HttpServletRequest request, HttpServletResponse response) {
    		ResultVO objResult = new ResultVO();
    		HessianProxyFactory factory = new HessianProxyFactory();
    		ILcamAttachmentProcess hessianServer = null;
    		try {
    			hessianServer = (ILcamAttachmentProcess) factory.create(ILcamAttachmentProcess.class, ATMUtil.getATM_URL());
    		} catch (MalformedURLException e) {
    			e.printStackTrace();
    		}
    		// 删除指定业务单下所有的附件
    		// boolean flag = hessianServer.deleteAllAttachment("attachment",
    		// "attachmentTest");
    		// 根据附件id删除附件
    		String[] attachmentIdArray = attachmentIds.split(",");
    		boolean flag = hessianServer.deleteAttachment(jobTypeCode, objectId, attachmentIdArray);
    		if (flag == true) {
    			objResult.setResultState(SUCCESS);
    			objResult.setResultData(attachmentIdArray.length);
    		} else {
    			objResult.setResultState(ERROR);
    		}
    		return objResult;
    	}
    

    工具类:ATMUtil.java

    public class ATMUtil {
    	/*
    	 * hessian接口地址
    	 */
    	private static final String ATM_URL;
    	
    	/*
    	 * 临时文件存放目录
    	 */
    	private static final String ATM_ROOTDIR;
    	/*
    	 * 临时分片文件存放目录
    	 */
    	private static final String ATM_TEMPDIR;
    	/*
    	 * 下载文件存放目录
    	 */
    	private static final String ATM_DOWNLOADDIR;
    	/*
    	 * 静态代码块
    	 */
    	static {
    		PropertiesLoader propertiesLoader = new PropertiesLoader("classpath:atm-config.properties");
    		ATM_URL = propertiesLoader.getProperty("atm.hessianUrl");
    		ATM_ROOTDIR =  propertiesLoader.getProperty("atm.rootDir");
    		ATM_TEMPDIR =  propertiesLoader.getProperty("atm.tempDir");
    		ATM_DOWNLOADDIR = propertiesLoader.getProperty("atm.downloadDir");
    	}
    	public static String getATM_URL(){
    		return ATM_URL;
    	}
    	public static String getATM_ROOTDIR(){
    		return ATM_ROOTDIR;
    	}
    	public static String getATM_TEMPDIR(){
    		return ATM_TEMPDIR;
    	}
    	public static String getATM_DOWNLOADDIR(){
    		return ATM_DOWNLOADDIR;
    	}
    	
    	/**
    	 * 创建临时目录,保存每个分片文件
    	 * @param file 每个分片文件
    	 * @param chunk 分片编号
    	 * @return 每个分片文件路径和文件名
    	 */
    	public static String saveChunk(MultipartFile file,String chunk){
    		//文件名
    		String fileName = file.getOriginalFilename();
    		//不带后缀的文件名
    		String onlyFileName = fileName.substring(0,fileName.lastIndexOf("."));
    		//文件带点的后缀名
    		String FileExt = fileName.substring(fileName.lastIndexOf("."));
    		//分片文件的临时目录
    		String tempDirectory = onlyFileName;
    		//临时文件名
    		String tempFile = onlyFileName + String.valueOf(chunk) + FileExt;
    		
    		//创建存放临时分片文件的目录
    		String fileUrl = ATM_TEMPDIR+tempDirectory+File.separator+tempFile;
    		File dirAndFile = new File(fileUrl);
    		File fileParent = dirAndFile.getParentFile();
    		if(!fileParent.exists()){
    			fileParent.mkdirs();
    		}
    		try{
    			//保存临时文件
    			file.transferTo(new File(fileUrl));
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    		return fileUrl;
    		
    	}
    	
    	/**
    	 * 上传附件
    	 * @param objAttachmentVO atm对象VO
    	 * @param fileInputStream 文件输入流
    	 * @return 
    	 */
    	public static AttachmentTransVO uploadAttachment(AttachmentTransVO objAttachmentVO,InputStream fileInputStream) throws Exception{
    		AttachmentTransVO result = new AttachmentTransVO();
    		HessianProxyFactory factory = new HessianProxyFactory();
    		ILcamAttachmentProcess hessianServer;
    		
    		if(objAttachmentVO == null){
    			throw new Exception("AttachmentTransVO附件对象不能为空");
    		}
    		try{
    			hessianServer = (ILcamAttachmentProcess)factory.create(ILcamAttachmentProcess.class, ATM_URL);
    			//调用ATM接口上传附件
    			String id = hessianServer.uploadAttachmentFile(objAttachmentVO, fileInputStream);
    			//根据attachmentId查询AttachmentTransVO对象信息
    			result = hessianServer.getAttachmentInfo(id);
    		}catch(MalformedURLException e){
    			e.printStackTrace();
    		}
    		return result;
    	}
    }
    

    工具类FileUtil.java

    public class FileUtil {
    
    	//删除文件夹
    	//param folderPath 文件夹完整绝对路径
    
    	     public static void delFolder(String folderPath) {
    	     try {
    	        delAllFile(folderPath); //删除完里面所有内容
    	        String filePath = folderPath;
    	        filePath = filePath.toString();
    	        java.io.File myFilePath = new java.io.File(filePath);
    	        myFilePath.delete(); //删除空文件夹
    	     } catch (Exception e) {
    	       e.printStackTrace(); 
    	     }
    	}
    
    	//删除指定文件夹下所有文件
    	//param path 文件夹完整绝对路径
    	   public static boolean delAllFile(String path) {
    	       boolean flag = false;
    	       File file = new File(path);
    	       if (!file.exists()) {
    	         return flag;
    	       }
    	       if (!file.isDirectory()) {
    	         return flag;
    	       }
    	       String[] tempList = file.list();
    	       File temp = null;
    	       for (int i = 0; i < tempList.length; i++) {
    	          if (path.endsWith(File.separator)) {
    	             temp = new File(path + tempList[i]);
    	          } else {
    	              temp = new File(path + File.separator + tempList[i]);
    	          }
    	          if (temp.isFile()) {
    	             temp.delete();
    	          }
    	          if (temp.isDirectory()) {
    	             delAllFile(path + File.separator + tempList[i]);//先删除文件夹里面的文件
    	             delFolder(path + File.separator + tempList[i]);//再删除空文件夹
    	             flag = true;
    	          }
    	       }
    	       return flag;
    	     }
    }
    

    3.问题总结:
    (1)当初在文件上传的时候总是报流关闭的错误Stream Closed ,最后解决办法是每次序列流写入的时候刷新一下(FileOutputStream)fos.flush();然后每个文件上传完后要清空一下合并分片的容器(Vector)v.clear();

    你可能感兴趣的:(javaweb,附件上传)