【SSH】Struts2文件上传

        文件上传也是项目中常用的功能,在之前做过的几个项目中,几乎每个项目都有个上传头像的功能。这次遇到的不是上传头像,而是需要上传pdf、图片等多种格式的文件了,而这个模块的主要业务逻辑就是围绕着这些文档来进行。所以文件上传、下载、预览都需要涉及。先整上传吧。

        设计数据库时有两种方案比较:

        一是把每次上传的文件地址拼接字符串放在一条记录里。二是每个文件对应一条记录。

        这两者的区别就是:

        前者,需要用js拼接文件路径等属性的字符串,对数据做查询排序等处理还需要查询出来后,用js等代码进行处理。插入一条记录即可。

        后者,存文件的五个属性(realname文件加密名、filename文件名、type类型、ext扩展名、path路径),日后查询处理更方便。一次上传多个文件,需要批量插入。除了存文件的属性外,其他的信息信息也要存,因此数据库冗余信息比较多。

        鉴于这个文件在此系统中需要频繁查询展示。所以选用第二种方式。

        输入流输出流上传 VS FileUtiles.copy上传

        //TODO:

        单文件上传 VS 多文件上传

        上传文件时一次选择多个文件,然后上传,可以在html页的<input  type = "file" name="upload" multiple />中添加"multiple"属性,h5支持,IE10+支持。

        还可以通过js动态生成多个input来达到一次上传多个文件的目的。

        文件上传有单文件上传和多文件上传,区别就是在action中接收从jsp页面传过来的file对象的值时,单文件用字符串,多文件用数组或list集合。

        在网上找到了demo,写的非常棒,既有讲解,又有源码,代码还比较严谨,链接给大家。基本的理解就是从他这里得来的。不过还是自己理一遍,思路更清晰。


Struts2文件上传,分两大步:

一、文件上传至服务器磁盘相应路径下:

        1、引入jar包

        //TODO:

        2、编写jsp

        在编写jsp时有两种方式:html编写或者s标签。

        网上查有两种说法:在速度上html的要优于s标签的。因为s标签解析比较费时间。但是在s标签<s:from>里设置theme="simple" 属性,s标签解析出来的html代码也就没有过多的冗余了,而且s标签的验证功能强大。两种方法都给大家列出来。

        html方式的:

<form action="uploadFile.action" enctype="multipart/form-data" method="post">	
	<table align="center" width="50%" border="1">
		<tr>
			<td>
				上传资料:
			</td>
			<td>
				<input type="file" multiple name="upload" id="file">
				<input type="submit" value="上传" />         	
			</td>			    
		</tr>	        
	 </table>  	    
</form>

        s标签的:

<s:form action="uploadFile.action" theme="simple" method="post"	enctype="multipart/form-data">
	<table align="center" width="50%" border="1">
		<tr>
			<td>
				上传文件
			</td>
			<td id="more" >
				<s:file name="upload" label="输入要上传的文件名"></s:file>
				<input type="button" value="上传更多..." οnclick="addMore()">
			</td>
		</tr>
		<tr>
			<td>
				<s:submit value="确认"></s:submit>
			</td>
			<td>
				<s:reset value="重置"></s:reset>
			</td>
		</tr>
	</table>
</s:form>

        显示上传文件验证结果的信息通过S标签显示如下:

<s:fielderror cssStyle="color:red" />
        通过拦截器的配置,检验上传文件的类型,大小是否合法,不合法将会通过上述标签显示出来。

       

         3、编写js

        有人家写好的,我就先搬过来用用啦。

    /* 上传多个文件上传 */
function addMore()
{
	var td = document.getElementById("more");
	var br = document.createElement("br");
	var input = document.createElement("input");
	var button = document.createElement("input");
	input.type = "file";
	input.name = "upload";
	button.type = "button";
	button.value = "   删除    ";
	button.onclick = function()
	{
		td.removeChild(this);	
	}
	td.appendChild(br);
	td.appendChild(input);
	td.appendChild(button);
};
			

        4、编写action

        需要定义几个必须的参数,用来获取文件信息,单个可以用String ,多个用数组或者list。

        下边是用数组的方式:

//上传多个文件
        private File[] upload;// 实际上传文件
	private String[] uploadContentType; // 文件的内容类型
	private String[] uploadFileName; // 上传文件名
	// 注意FileName和ContentType 必须这样写!以你的<input type="file" name="upload">
	private List<entity> entityList = new ArrayList<entity>();// 上传文件集合
	private String message;
	public static String FILE_ROOT = "";
	public static String UPLOAD_PATH = "/upload"; // 上传文件路径

//......省略相应的get、set方法

        这是把文件的属性信息进行处理,存入实体对象中,准备存入数据库,进行数据持久化。
	try{
		String path = ServletActionContext.getServletContext().getRealPath(FILE_ROOT);
		String path2 = UPLOAD_PATH + "/testUpload/";
		String targetDirectory = path + path2;
		File file = new File(targetDirectory);// 获取文件流路径
		if (!file.exists()) {
			file.mkdirs();
		}
				
		for(int i = 0; i < upload.length; i++){
			String fileName = uploadFileName[i];// 上传的文件名
			String type = uploadContentType[i];// 文件类型
			String realName = UUID.randomUUID().toString()
					+ getExt(fileName);// 保存的文件名称,使用UUID+后缀进行保存
			File target = new File(targetDirectory, realName);
			FileUtils.copyFile(upload[i], target);// 上传至服务器的目录
					
					
			entity.setsFilePath(path2 + realName);
			entity.setsFileExt(getExt(fileName));
			entity.setsFileType(type);
			entity.setsFileName(fileName);//上传的文件名称
			entity.setsFileRealName(realName);//保存数据库的文件名称 采用加密形式
			entity.setId(UUIDHexGenerator.getUUID());
			entity.setdCreateDate(new Date());
			//省略 entity....;

					
			entityList.add(entityInspect);
					
		}
		entityService.saveOrUpdateEntityList(entityList);//调用service层保存方法
				
	} catch (Exception e) {
		e.printStackTrace();
		addActionError(e.getMessage());
	}

        5、配置struts.xml 

        <!--fileUpload拦截器,可用于限制上传文档的类型和文档大小 -->
        <interceptor-ref name="fileUpload">
		<!--限制文件大小20M,单位为字节-->
		<param name="maximumSize">20971520</param>	
		<!--配置可上传文件类型为doc,ppt,xls,pdf,txt,word,zip,-->
		<param name="allowedTypes">
			image/bmp,image/x-png,image/png,image/gif,image/jpeg,image/jpg,image/pjpeg,
			application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document,
			application/pdf,application/vnd.ms-excel,application/vnd.ms-powerpoint,text/plain,
			application/zip,application/x-zip-compressed
		</param>
		<!-- 配置路径,创建/image文件夹 -->
        	<!-- <param name="savePath">/image</param> -->
	</interceptor-ref>
		<interceptor-ref name="defaultStack"/>
		
         <!-- 若上传的文件不符合要求则返回input --> 
		<result name="input">/pages/common/error.jsp</result>
           在struts中配置是为了拦截上传的文件,进行合法性验证,当上传的文件大小超过设定的大小,文件类型不在被允许范围内时,上传失败,返回错误信息,默认返回input,跳转input设置的页面。该页面上设置  s:fielderror 标签,则会把具体的验证信息显示出来。

        文件类型设置需用mine,具体戳这里,非常详细。


二、把文件参数存入数据库:(到action就够了,剩下这几步就不细写了

        6、编写entity(vo)(实体在action中也会用,可以早点设计好)

        7、编写service

        8、编写dao


总结:

        都是基础,需要积累啊~~

        项目中多个地方需要文件上传,想把它再封装一下,正在努力中。。。

        考虑不周之处,还请大家指正~感激不尽。


评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值