struts2文件上传

13 篇文章 0 订阅

文件上传

一、上传下载组件介绍

jspSmartUpload(model1的年代);

apache-commons-fileupload,Struts2默认上传组件;

Servlet3.0使用的Part,但Servlet3.0还没有普及;

COS,Struts2支持,不过已经停止更新很久了;

pell,Struts2支持。

 

二、fileUpload的拦截器

Struts2默认使用的是commons-fileUpload组件完成上传的,使用Struts2会大量简化上传文件的开发。

这一工作由fileUpload拦截器来完成。

它会查看当前请求的enctype是否为multipart/form-data,如果不是就会直接“放行”;

如果是,那么它会去解析表单,然后把解析的结果传递给Action的属性!

  fileUpload拦截器对会对Action提供很大的“帮助”,同时它也会对Action提出一些“小小的要求”。

Action需要提供3个属性:

private File myUpload

private String myUploadContentType

private String myUploadFileName

 

三、演示上传

上传文件首先我们需要给出一个页面,页面中要有一个表单:

upload.jsp

<form action="<c:url value='/UploadAction.action'/>" method="post" enctype="multipart/form-data">
    	用户名: <input type="text" name="username"/><br/>
    	文 件:<input type="file" name="myUpload"/><br/>
        <input type="submit" value="Submit"/>
    </form>

 

UploadAction

public class UploadAction extends ActionSupport {
	private String username;
	
	public void setUsername(String username) {
		this.username = username;
	}

	private File myUpload;
	private String myUploadContentType;
	private String myUploadFileName;
        private String savepath = "/WEB-INF/uploads";

	public void setMyUpload(File myUpload) {
		this.myUpload = myUpload;
	}

	public void setMyUploadContentType(String myUploadContentType) {
		this.myUploadContentType = myUploadContentType;
	}

	public void setMyUploadFileName(String myUploadFileName) {
		this.myUploadFileName = myUploadFileName;
	}

	public String execute() throws Exception {
		System.out.println(username);
		System.out.println(this.myUploadContentType);
		System.out.println(this.myUploadFileName);
		System.out.println(this.myUpload.getAbsolutePath());
		this.savepath = ServletActionContext.getServletContext().getRealPath(savepath);
		File destFile = new File(savepath, myUploadFileName);
		FileUtils.copyFile(myUpload, destFile);
		return NONE;
	}
}
 
 

struts.xml

<package name="s8" namespace="/" extends="struts-default">
		<action name="UploadAction" class="cn.hcx.upload.action.UploadAction">
		</action>
	</package>

 

四、上传配置

可以通过Struts2的常量来完成对上传的配置,下面是与上传相关的常量:

struts.multipart.parser:指定使用的上传组件,默认值为jakarta,表示使用commons-fileupload组件,Struts2还支持cos和pell;

struts.multipart.saveDir:临时目录,如果没有指定临时目录,那么临时文件会在Tomcat的work目录中;

struts.multipart.maxSize:整个大小限制,默认值为2097152,即2M。注意,这个限制是整个请求的大小,而不是单一文件的大小。

当上传的表单超出了限制时,拦截器会向fieldError中添加错误信息!

当执行wokflow拦截器时,会发现fieldError中存在错误,这时就会跳转到input视图,所以我们需要为Action指定input视图。

case:

 

<struts>
	
	
	<!-- 指定文件上传时临时文件所在目录 -->
	<constant name="struts.multipart.saveDir" value="d:/temp"></constant>
	<!--  文件上传大小限制(总闸) -->
	<constant name="struts.multipart.maxSize" value="12097152"></constant>
	
	
	<package name="upload" namespace="/upload" extends="struts-default" >
	<interceptors>
	<!-- 自己配置一个拦截器栈 -->
		<interceptor-stack name="defaultStack2">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="i18n"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="chain"/>
                <interceptor-ref name="scopedModelDriven"/>
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="fileUpload">
                	<param name="maximumSize">12097152</param>
                	<param name="allowedExtensions">jpg,jpeg,bmp</param>
                	<param name="allowedTypes">image/pjpeg</param>
                </interceptor-ref>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="multiselect"/>
                <interceptor-ref name="staticParams"/>
                <interceptor-ref name="actionMappingParams"/>
                <interceptor-ref name="params">
                    <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
                </interceptor-ref>
                <interceptor-ref name="conversionError"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
                <interceptor-ref name="debugging"/>
            </interceptor-stack>
            
	</interceptors>
		
	<default-interceptor-ref name="defaultStack2"></default-interceptor-ref>
	
		<action name="Demo1Action" class="cn.hcx.e_fileupload.Demo1Action">
			<result>/upload/demo1.jsp</result>
			<result name="input">/upload/demo1.jsp</result>
			
		</action>
		<action name="Demo2Action" class="cn.hcx.e_fileupload.Demo2Action">
			<result>/upload/demo2.jsp</result>
			<result name="input">/upload/demo2.jsp</result>
		</action>
	</package>
</struts>
修改提示信息:(重写配置文件中的信息)

 

fileUpload拦截器也有3个参数,我们可以给fileUpload拦截器配置这3个参数:

  • maximumSize:上传的单个文件的大小限制;
  • allowedTypes:允许上传文件的类型,多个类型以逗号隔开;
  • allowedExtensions:允许上传文件的扩展名,多个扩展名以逗号隔开;
<struts>
	<constant name="struts.devMode" value="true" />
	<constant name="struts.multipart.maxSize" value="1048576" />
	<package name="s8" namespace="/" extends="struts-default">
		<action name="UploadAction" class="cn.hcx.upload.action.UploadAction">
			<result name="input">/demo1/upload.jsp</result>
			<param name="savepath">/WEB-INF/uploads</param>
			<interceptor-ref name="defaultStack">
				<!-- 限制单个文件大小上限为512K -->
				<param name="fileUpload.maximumSize">524288</param>
				<param name="fileUpload.allowedExtensions">jpg,png,bmp</param>
			</interceptor-ref>
		</action>
	</package>
</struts>

 

五、上传相关的错误信息国际化

在上传文件时如果出现错误,那么在input视图显示的错误信息都是英文的。

如果想替换这些信息,需要知道这些错误信息的资源key,然后在我们自己的国际化资源文件中指定这些key的新值即可。

与上传相关的错误信息都在org.apache.struts2包下的struts-message.properties文件中。

struts.messages.error.uploading=Error uploading: {0}
struts.messages.error.file.too.large=The file is to large to be uploaded: {0} "{1}" "{2}" {3}
struts.messages.error.content.type.not.allowed=Content-Type not allowed: {0} "{1}" "{2}" {3}
struts.messages.error.file.extension.not.allowed=File extension not allowed: {0} "{1}" "{2}" {3}
struts.messages.upload.error.SizeLimitExceededException=Request exceeded allowed size limit! Max size allowed is: {0} but request was: {1}!
 

我们可以在src下res.properties文件,在这个文件中对象以上资源key进行替换。

然后在struts.xml文件中给出<constant name="struts.custom.i18n.resources"value="res/">即可。

 
 
上传case:
jsp:
 <body>
  	<s:form action="Demo1Action" method="post" namespace="/upload" enctype="multipart/form-data" >
  		<s:file name="file" label="文件上传" ></s:file>
  		<s:submit value="上传" ></s:submit>
  	</s:form>
  	<s:actionerror/>
  	<s:debug></s:debug>
  </body>

 
action:
package cn.hcx.e_fileupload;

import java.io.File;
import java.util.UUID;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class Demo1Action extends ActionSupport {
	
	private File file; //跟表单提交的键一致
	private String fileContentType;
	private String fileFileName;
	
	

	public String getFileContentType() {
		return fileContentType;
	}



	public void setFileContentType(String fileContentType) {
		this.fileContentType = fileContentType;
	}



	public String getFileFileName() {
		return fileFileName;
	}



	public void setFileFileName(String fileFileName) {
		this.fileFileName = fileFileName;
	}



	public File getFile() {
		return file;
	}



	public void setFile(File file) {
		this.file = file;
	}



	@Override
	//将文件放入 res文件夹下
	public String execute() throws Exception {
		
		System.out.println(file);
		//----------------------------
		//1 获得res文件夹的路径
		String dirPath = ServletActionContext.getServletContext().getRealPath("/res");
		//2 创建目标文件
		String fileName = UUID.randomUUID().toString();
		File target = new File(dirPath+"/"+fileName);
		//3 将file拷贝到目标文件中
		file.renameTo(target);
		//----------------------------------
		System.out.println("上传文件的Mime类型:"+fileContentType);
		System.out.println("上传文件的文件名称:"+fileFileName);
		return SUCCESS;
	}
	
	
	
}
 
struts.xml:
<action name="Demo1Action" class="cn.hcx.e_fileupload.Demo1Action">
			<result>/upload/demo1.jsp</result>
			<result name="input">/upload/demo1.jsp</result>
			
		</action>

 

六、多文件上传

当需要上传多个文件时,如果每个<input type=”file”>对应Action的3个属性,那么这会使Action的属性过多的现象。

处理这一问题的方法是在表单中设置所有<input type=”file”>的名称为相同名称,然后在Action中给出数组属性即可。

uploads.jsp

<s:fielderror />
    <s:actionerror/>
    <form action="<c:url value='/UploadsAction.action'/>" method="post" enctype="multipart/form-data">
    	用户名: <input type="text" name="username"/><br/>
    	文 件1:<input type="file" name="myUpload"/><br/>
    	文 件2:<input type="file" name="myUpload"/><br/>
    	文 件3:<input type="file" name="myUpload"/><br/>
        <input type="submit" value="Submit"/>
    </form>

 

UploadsAction

public class UploadsAction extends ActionSupport {
	private File[] myUpload;
	private String[] myUploadContentType;
	private String[] myUploadFileName;
	private String savepath;
	public void setSavepath(String savepath) {
		this.savepath = savepath;
	}
	public void setMyUpload(File[] myUpload) {
		this.myUpload = myUpload;
	}
	public void setMyUploadContentType(String[] myUploadContentType) {
		this.myUploadContentType = myUploadContentType;
	}
	public void setMyUploadFileName(String[] myUploadFileName) {
		this.myUploadFileName = myUploadFileName;
	}
	public String execute() throws Exception {
		savepath = ServletActionContext.getServletContext().getRealPath(savepath);
		for(int i = 0; i < myUpload.length; i++) {
			System.out.println("文件名:" + myUploadFileName[i]);
			System.out.println("文件类型:" + myUploadContentType[i]);
			FileUtils.copyFile(myUpload[i], new File(savepath, myUploadFileName[i]));
		}
		return NONE;
	}
}
 

其中Struts2也允许我们使用List类型来代替数组属性。

UploadsAction.java

public class UploadsAction extends ActionSupport {
	private List<File> myUpload;
	private List<String> myUploadContentType;
	private List<String> myUploadFileName;
…
}
 
case:
jsp:
<body>
  	<s:form action="Demo2Action" method="post" namespace="/upload" enctype="multipart/form-data" >
  		<s:file name="file" label="文件上传" ></s:file>
  		<s:file name="file" label="文件上传" ></s:file>
  		<s:file name="file" label="文件上传" ></s:file>
  		<s:submit value="上传" ></s:submit>
  	</s:form>
  	<s:actionerror/>
  	<s:debug></s:debug>
  </body>
 
action:
package cn.hcx.e_fileupload;

import java.io.File;
import java.util.Arrays;
import java.util.UUID;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class Demo2Action extends ActionSupport {
	
	private File[] file;
	private String[] fileContentType;
	private String[] fileFileName;
	
	



	public File[] getFile() {
		return file;
	}





	public void setFile(File[] file) {
		this.file = file;
	}





	public String[] getFileContentType() {
		return fileContentType;
	}





	public void setFileContentType(String[] fileContentType) {
		this.fileContentType = fileContentType;
	}





	public String[] getFileFileName() {
		return fileFileName;
	}





	public void setFileFileName(String[] fileFileName) {
		this.fileFileName = fileFileName;
	}





	@Override
	//将文件放入 res文件夹下
	public String execute() throws Exception {
		System.out.println("上传文件:"+Arrays.toString(file));
		System.out.println("上传文件的Mime类型:"+Arrays.toString(fileContentType));
		System.out.println("上传文件的文件名称:"+Arrays.toString(fileFileName));
		return SUCCESS;
	}
	
	
	
}

 
 
 
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值