首页 > WEB开发 > 后台开发 > Struts2结果类型、拦截器及文件上传下载
2014
09-13

Struts2结果类型、拦截器及文件上传下载

3、自定义拦截器(二)

上面定义的拦截器会对所有action请求起作用,Struts中还提供了一类拦截器:MethodFilterInterceptor,该拦截器可以过滤指定的action请求,也可以只对指定的action请求起作用。

MethodFilterInterceptor类继承了AbstractInterceptor,该类在intercept()方法中增加了判断当前action请求是否在拦截范围内的功能,如果在,则调用doIntercept方法。因此在继承MethodFilterInterceptor时,只需覆写其中的doIntercept方法即可。

案例:自定义一个登录验证拦截器,对于没有登录时的action请求直接转发到LOGIN视图。

分析:由于登录时会向名为login的action发出请求,因此登录验证拦截器不能对login请求进行拦截,否则永远只能停留在登录视图了。注:用户是否登录通过session属性范围内有没有user对象来判定。

public class LogCheckInterceptor extends MethodFilterInterceptor {
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		HttpSession session = ServletActionContext.getRequest().getSession();
		User user = (User)session.getAttribute("user");
		if(user == null){//如果用户没有登录,则直接转发到login视图
			return "login";
		}
		return invocation.invoke();
	}
}

关于该拦截器的配置及说明见下图:

03. Struts2结果类型、拦截器及文件上传下载5500

三、文件的上传和下载

查看Struts2工程中引入的jar包可以推测,其底层也是commons-fileupload,Struts2只是对其做了一些封装并提供了自己的上传下载API。本节利用Struts2提供的API实现文件上传和下载。

1、文件上传

1)fileUpload拦截器

Struts2中的文件上传是由fileUpload拦截器实现的,该拦截器会去解析表单中的file字段,并将解析的结果传递给动作类中的属性。在动作类中需要提供下面三个属性:

  • File fieldName; //和表单的文件上传字段名称一致,必须是File类型
  • String fieldNameFileName; //文件名:文件上传字段名称+FileName
  • String fieldNameContentType; //上传字段的MIME类型

2)单文件上传(最基本)

03. Struts2结果类型、拦截器及文件上传下载5944

3)限制文件大小、类型:配置fileUpload拦截器

fileUpload拦截器对应着FileUploadInterceptor类,该有maximumSize、allowedTypes、allowedExtensions等属性(由setXxx决定),因此配置fileUpload拦截器时,对应的也有三个参数,如下图:

03. Struts2结果类型、拦截器及文件上传下载6107

说明:

① 由于fileUpload拦截器已经包含在defaultStack中,因此采用上图的配置方式(☆)。

② 文件大小的单位为字节,默认为2M。当上传的文件超出了限制时,拦截器会向actionError中添加错误信息!当执行workflow拦截器时,会发现actionError中存在错误,这时就会跳转到input视图,所以我们需要为Action指定input视图。

4)配置上传错误时的提示信息:国际化相关

在上传文件时如果出现错误,那么在input视图显示的错误提示信息都是英文的。如果想替换这些信息,需要知道这些错误信息的资源key,然后在我们自己的国际化资源文件中指定这些key的新值即可。

与上传相关的错误提示信息都在struts2-core.jar /org /apache /struts2 /struts-message.properties中。如下:

03. Struts2结果类型、拦截器及文件上传下载6498

我们可以在src下创建res.properties文件,对上面的key进行替换:

03. Struts2结果类型、拦截器及文件上传下载6541

然后在struts.xml文件中加载该资源文件即可:<constant name=”struts.custom.i18n.resources” value=”res” />

5)多文件上传:

在文件输入域中使用相同的字段名称,在动作类中的相关属性用数组或List类型即可。相关代码片段如下:

multiUpload.jsp:------------------
文件1:<input type="file" name="files"/><br/>
文件2:<input type="file" name="files"/><br/>
文件3:<input type="file" name="files"/><br/>

MultiUploadAction:-----------------
public class MultiUploadAction extends ActionSupport {
	private File[] files;
	private String[] filesFileName;
	private String[] filesContentType;

	public String doMultiUpload() throws Exception{
		//指定文件存放位置
		String storeDir = ServletActionContext.getServletContext()
									.getRealPath("/WEB-INF/files");
		//上传
		for(int i = 0 ;i < files.length;i ++){
			FileUtils.copyFile(files[i], new File(storeDir, filesFileName[i]));
		}
		return NONE;
	}
……………………setter方法略…………………………
}

2、文件下载

1)stream结果类型

在Struts2中,所有与响应相关的工作都由<result>来处理。stream类型的result用来完成下载,对应着StreamResult类,这个类用来设置响应头,以及向response.getOutputStream()中写入数据。该类中的属性(setXxx)如下:

  • contentType:默认为text/plain,一般需要自己设置。
  • contentDisposition:默认为inline,需要自己设置,一般为attachment;filename=xxx
  • inputName:默认为”inputStream”。可以直接使用默认值,此时需要在动作类中提供一个getInputStream方法,StreamResult类会通过该方法获取一个InputStream对象,并将该输入流中的内容写入到response.getOutputStream()中。

这些属性值可以在配置<result type=”stream”>元素时指定。

2)文件下载(硬编码)

download.jsp-------------------
<a href="${pageContext.request.contextPath }/download.action">下载此图</a>
DownloadAction-------------------
public class DownloadAction extends ActionSupport {
	public InputStream getInputStream() throws Exception{
		String storeDir = ServletActionContext.getServletContext()
									.getRealPath("/WEB-INF/files");
		return new FileInputStream(storeDir + "/QQ.jpg");
	}

	public String download(){
		return SUCCESS;
	}
}
struts.xml-------------------
<action name="download" class="org.flyne.action.DownloadAction" method="download">
	<result type="stream">
		<param name="contentType">image/jpeg</param>
		<param name="contentDisposition">attachment;filename=qq.jpg</param>
	</result>
</action>

案例中中要下载的文件是硬编码,文件的ContentType类型是硬编码,下载框中的文件名也是硬编码,这些都是需要处理的。

3)通过OGNL获取动Action属性值

对上面的代码进行改进,<action>元素的配置及说明如下:

03. Struts2结果类型、拦截器及文件上传下载8675

动作类如下所示:

public class DownloadAction extends ActionSupport {
	private String storeDir;//存储目录

	private String filename;//文件名
	private InputStream inputStream;//文件输入流,给StreamResult用的

	public String download() throws FileNotFoundException{
		storeDir = ServletActionContext.getServletContext()
				.getRealPath(storeDir);
		filename = "QQ.jpg";//filename一般通过程序获得(如从数据库中取出)

		inputStream = new FileInputStream(storeDir + "/" + filename);
		return SUCCESS;
	}

	public void setStoreDir(String storeDir) {
		this.storeDir = storeDir;
	}

	public InputStream getInputStream(){
		return inputStream;
	}

	public String getFilename() {
		return filename;
	}

	public String getContentType() {
		// 文件的MIME类型
		return ServletActionContext.getServletContext().getMimeType(filename);
	}
}

留下一个回复

你的email不会被公开。