JavaWeb开发中重新认识文件上传

        文件上传功能在很多软件中都是必备的功能之一,所以,文件上传也就不显得那么有技术含量了,但是如果要把这个功能做好甚至完美,可不是三两下就能搞定的,其中包含的诸多细节尽在不言中。我们来看一下,做一个上传功能需要考虑什么,以apk文件上传为例:

       1、上传的文件的类型(选择文件时对文件格式做限制)

       2、上传的文件的大小(设置文件上传的最大范围)

       3、上传的文件的名称(这里包括加密后的名称和realName)

       4、删除文件(必须考虑是否能真正删除)

       5、修改时能否回显文件

       6、修改后保存文件应该怎么对文件进行处理

       7、单独复制文件绝对路径能否下载

       8、文件的相对路径生成

       虽然总结出了八条需要考虑的点,但应该还是存在欠缺的地方的。常用的上传方式有两种:异步上传和同步上传,现在好像异步上传用的比较多一些,下面先以同步上传方式来说说吧:

       同步上传就是先仅仅选择一个文件,填完其它内容后再统一提交到后台,在后台做文件上传的逻辑处理并保存一个完整内容。一般来说,我们在数据库中都会用一个字段(URL)来存储文件的相对路径,但是这个最终存储到数据库里的URL是要在后台生成的,因此,提交表单时将文件同请求一起发送到后台即可。下面以app版本管理功能为例讲解。

       app版本添加页面:


JSP代码:

<form:form id="inputForm" modelAttribute="safeFireAppVersion" action="${ctx}/safe/fire/safeFireAppVersion/save" method="post" class="form-horizontal"
		enctype="multipart/form-data">
		<form:hidden path="id"/>
		<sys:message content="${message}"/>		
		<div class="control-group">
			<label class="control-label">版本号:</label>
			<div class="controls">
				<form:input path="code" htmlEscape="false" maxlength="16" class="input-xlarge required"/>
				<span class="help-inline"><font color="red">*</font> </span>
			</div>
		</div>
		<div class="control-group">
			<label class="control-label">版本数:</label>
			<div class="controls">
				<form:input path="codenum" htmlEscape="false" maxlength="3" class="input-xlarge required"
					οnkeyup="this.value=this.value.replace(/\D/g,'')"
					onafterpaste="this.value=this.value.replace(/\D/g,'')" />
				<span class="help-inline"><font color="red">*</font> </span>
			</div>
		</div>
		<div class="control-group">
			<label class="control-label">文件:</label>
			<div class="controls">
				<form:input path="" type="file" name="apkFile" accept=".apk"/>
				<br/>${safeFireAppVersion.realName }
			</div>
		</div>		
		<div class="control-group">
			<label class="control-label">备注:</label>
			<div class="controls">
				<form:textarea path="remarks" htmlEscape="false" rows="4" maxlength="255" class="input-xxlarge "/>
			</div>
		</div>
		<div class="form-actions">
			<shiro:hasPermission name="safe:fire:safeFireAppVersion:edit"><input id="btnSubmit" class="btn btn-primary" type="submit" value="保 存"/> </shiro:hasPermission>
			<input id="btnCancel" class="btn" type="button" value="返 回" οnclick="history.go(-1)"/>
		</div>
	</form:form>
        通过观察代码可以发现,path属性的名称与这个实体对象的属性相对应且名称相同,提交表单时会自动把这些属性的值存到modelAttribute中传到后台,我们不可以直接选择文件后就直接得到相对路径存到modelAttribute中,只有经过后台处理后才可以进行存储,所以,在页面中文件只是一个独立的文件而已,path的值可以不填甚至不要这个属性,但是name属性是必须要用到的,这是用于后台识别文件的唯一标识。这就好比采摘水果,传统售卖摘下来就可以拿去卖了,因为客户需要的只是普通水果,而果汁饮料需要采摘下来再加工后做成饮料产品才能满足客户需求。

        表单提交的方式为POST,我们只要在后台利用Springmvc的@RequestParam注解就可以对前台发送过来的文件进行接收了。后台代码如下:

@RequiresPermissions("safe:fire:safeFireAppVersion:edit")
	@RequestMapping(value = "save")
	public String save(@RequestParam("apkFile") MultipartFile apkFile, SafeFireAppVersion safeFireAppVersion, Model model, RedirectAttributes redirectAttributes) throws Exception {
		if (!beanValidator(model, safeFireAppVersion)) {
			return form(safeFireAppVersion, model);
		}
		if (!apkFile.isEmpty()) { // 判断文件是否为空
			String oldPath = null;
			if(!safeFireAppVersion.getIsNewRecord()){ // 判断是否是新记录,不是的话就是修改中的保存
				SafeFireAppVersion old = safeFireAppVersionService.get(safeFireAppVersion); // 获取原先的文件
				FileUtils.delFileByPath(old.getUrl());	// 删除原文件
				oldPath = old.getUrl(); // 获取原先的文件的路径,用于保留之前的uuid,换了文件还是用之前的uuid作为加密后的文件名
			}
			String filePath = UploadUtils.appVersionUpload(FireConstant.UPLOAD_VERSION_PATH, apkFile, oldPath); // 开始文件上传
			safeFireAppVersion.setUrl(filePath);
			safeFireAppVersion.setRealName(apkFile.getOriginalFilename()); // 真实名称
		}
		safeFireAppVersionService.save(safeFireAppVersion);
		addMessage(redirectAttributes, "保存灭火器APP版本信息成功");
		return "redirect:" + Global.getAdminPath() + "/safe/fire/safeFireAppVersion/?repage";
	}







  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值