假设有如图4.22所示的文件上传页面,其中包含两个表单域:文件标题和文件域——当然,为了能完成文件上传,我们应该将这两个表单域所在表单的enctype属性设置为“multipart/form-data”。该页面的代码如下。
程序清单:codes\04\4.3\simpleUpload\WEB-INF\content\upload.jsp
- <%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
- <%@taglib prefix="s" uri="/struts-tags"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>简单的文件上传</title>
- </head>
- <body>
- <s:form action="uploadPro"
- enctype="multipart/form-data">
- <s:textfield name="title" label="文件标题"/><br />
- <s:file name="upload" label="选择文件"/><br />
- <s:submit value="上传"/>
- </s:form>
- </body>
- </html>
上面的页面使用了Struts 2的标签库来生成上传文件的表单,其中<s:file…/>用于生成一个文件上传域。当该页面提交请求时,请求发送到uploadPro.action,这是Struts 2的一个Action。
Struts 2的Action无须负责处理HttpServletRequest请求,正如前面介绍的,Struts 2的Action已经与Servlet API彻底分离了,Struts 2框架负责解析HttpServletRequest请求中的参数,包括文件域,Struts 2使用File类型来封装文件域。下面是处理上传请求的Action类代码。
程序清单:codes\04\4.3\simpleUpload\WEB-INF\src\org\crazyit\app\action\UploadAction.java
- public class UploadAction extends ActionSupport
- {
- //封装文件标题请求参数的属性
- private String title;
- //封装上传文件域的属性
- private File upload;
- //封装上传文件类型的属性
- private String uploadContentType;
- //封装上传文件名的属性
- private String uploadFileName;
- //直接在struts.xml文件中配置的属性
- private String savePath;
- //接受struts.xml文件配置值的方法
- public void setSavePath(String value)
- {
- this.savePath = value;
- }
- //返回上传文件的保存位置
- private String getSavePath() throws Exception
- {
- return ServletActionContext.getServletContext()
- .getRealPath("/WEB-INF/" + savePath);
- }
- //文件标题的setter和getter方法
- public void setTitle(String title)
- {
- this.title = title;
- }
- public String getTitle()
- {
- return (this.title);
- }
- //上传文件对应文件内容的setter和getter方法
- public void setUpload(File upload)
- {
- this.upload = upload;
- }
- public File getUpload()
- {
- return (this.upload);
- }
- //上传文件的文件类型的setter和getter方法
- public void setUploadContentType(String uploadContentType)
- {
- this.uploadContentType = uploadContentType;
- }
- public String getUploadContentType()
- {
- return (this.uploadContentType);
- }
- //上传文件的文件名的setter和getter方法
- public void setUploadFileName(String uploadFileName)
- {
- this.uploadFileName = uploadFileName;
- }
- public String getUploadFileName()
- {
- return (this.uploadFileName);
- }
- @Override
- public String execute() throws Exception
- {
- //以服务器的文件保存地址和原文件名建立上传文件输出流
- FileOutputStream fos = new FileOutputStream(getSavePath()
- + "\\" + getUploadFileName());
- FileInputStream fis = new FileInputStream(getUpload());
- byte[] buffer = new byte[1024];
- int len = 0;
- while ((len = fis.read(buffer)) > 0)
- {
- fos.write(buffer , 0 , len);
- }
- return SUCCESS;
- }
- }
上面的Action与普通的Action并没有太大的不同,一样提供了upload和title两个属性,这两个属性分别对应前面的两个表单域的name属性,用于封装两个表单域的请求参数。
值得注意的是,上面的Action还包含了两个属性:uploadFileName和uploadContentType(如上粗体字代码所示),这两个属性分别用于封装上传文件的文件名、上传文件的文件类型。这两个属性,体现了Struts 2设计的灵巧、简化之处,Action类直接通过File类型属性直接封装了上传文件的文件内容,但这个File属性无法获取上传文件的文件名和文件类型,所以Struts 2直接将文件域中包含的上传文件名和文件类型的信息封装到uploadFileName和uploadContentType属性中。可以认为:如果表单中包含一个name属性为xxx的文件域,则对应Action需要使用三个属性来封装该文件域的信息。
Ø 类型为File的xxx属性封装了该文件域对应的文件内容。
Ø 类型为String的xxxFileName属性封装了该文件域对应的文件的文件名。
Ø 类型为String的xxxContentType属性封装了该文件域对应的文件的文件类型。
通过上面的3个属性,可以更简单地实现文件上传,所以在execute方法中,可以直接通过调用getXxx()方法来获取上传文件的文件名、文件类型和文件内容。
除此之外,上面的Action中还包含了一个savePath属性,该属性的值通过配置文件来设置,从而允许动态设置该属性的值。
|
Struts 2的Action中的属性,功能非常丰富,除了可以用于封装HTTP请求参数外,也可以封装Action的处理结果。不仅如此,Action的属性还可通过在Struts 2配置文件中进行配置,接收Struts 2框架的注入,允许在配置文件中为该属性动态指定值
本文转自fkJava李刚
51CTO博客,原文链接:http://blog.51cto.com/javaligang/887975 ,如需转载请自行联系原作者