您的位置:首页 > 编程语言 > Java开发

struts2学习笔记(11)——struts2文件上传与下载

2009-11-11 13:44 405 查看
首先,我们需要将之前注释的struts2框架引用取消注释。

在webroot下新建upload.jsp,在这里我使用struts2标签,同样在这个表单里,我们使用2个普通文本域和一个文件域。

<s:form action="upload" method="post" enctype="multipart/form-data">

<s:textfield name="username" label="username"></s:textfield>

<s:password name="password" label="password"></s:password>

<s:file name="file" label="file"></s:file>

<s:submit value=" submit "></s:submit>

</s:form>


表单将提交到upload这个Action。

为了防止干扰,首先我们注释掉所有的拦截器。

接下来重点是如何写这个Action。

表单中有3个字段,一个username,一个password和一个file。

username和password是String类型的,但是file该如何表示呢?

在struts2中,file的数据类型就是用File表示的,但是表示一个文件不仅仅需要用这个File对象,还需要2个String类型的对象,

分别表示文件名和文件类型,而且名字有固定的格式。

如上面的示例中:

private String username;

private String password;

private File file;

private String fileFileName;

private String fileContentType;


如何得知怎么表示文件名和文件类型呢?

查看struts-core-2.1.8.jar,包org.apache.struts2.interceptor下的类FileUploadInterceptor。

在其intercept方法中会看到

String contentTypeName = inputName + "ContentType";

String fileNameName = inputName + "FileName";


在示例中,也就是指明另两个字段分别是file+"ContentType"和file+"FileName",即fileContentType和fileFileName。

然后产生上述5个字段的set和get方法。

然后需要写Action的execute方法,这个方法完成了文件上传的IO操作。

public String execute() throws Exception {

InputStream is = new FileInputStream(file);

String path = ServletActionContext.getRequest().getRealPath("/upload");

OutputStream os = new FileOutputStream(new File(path, this
.getFileFileName()));

byte[] buffer = new byte[400];

int length = 0;

while ((length = is.read(buffer)) > 0) {

os.write(buffer, 0, length);

}

is.close();

os.close();

return SUCCESS;
}


这个方法中的大部分操作和之前fileupload组件上传的类似。

有些区别的是,在Action中要想获得文件的真实路径,必须借助于ServletActionContext,这个可以获得Servlet的上下文,也就可以

获得Servlet中的一些属性和方法。

然后需要配置struts.xml

<action name="upload" class="cn.tshining.action.UploadAction">

<result name="success">/uploadresult.jsp</result>

</action>


定义一个结果显示页面uploadresult.jsp,内容为:

username : <s:property value="username"/><br/>

password : <s:property value="password"/><br/>

file : <s:property value="fileFileName"/><br/>


这样就可以完成一个简单的上传了。

但是在控制台中看到如下输出:

信息: Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir

信息: Removing file file D:/WEB/Tomcat 6.0/work/Catalina/localhost/struts2/upload_46423892_124e323eb54__8000_00000002.tmp
这是什么意思呢?

第一条是:无法找到'struts.multipart.saveDir'属性设置,默认为javax.servlet.context.tempdir的值。

前面已经提到,在文件上传中,当超过一定大小的文件首先会存到磁盘中,然后再写到目的地。而不是都存在内存中。

同样查看struts-core-2.1.8.jar,包org.apache.struts2下的default.properties,这个文件就定义了struts2中的很多的默认属性,其中struts.multipart.saveDir并没有定义任何值。

我们可以在struts.xml中进行定义。

在struts根目录下加入如下内容

<constant name="struts.multipart.saveDir" value="C:/"></constant>


这样就为struts.multipart.saveDir指定了一个值,即临时目录为C盘。

这样就不会出现之前的第一条提示了。

但是注意到,我们在上传含有中文名的文件时会出现乱码!

这个如何解决呢?

同样在default.properties中有个设置为struts.i18n.encoding=UTF-8

只要将这个值改为中文字符集就可以了。

<constant name="struts.i18n.encoding" value="gbk"></constant>


这样就可以正常显示中文了。

在这个default.properties中定义了

struts.multipart.maxSize=2097152

即,默认允许上传当个文件最大值为2M,当然我们也可以修改这个值。

当然这仅仅只是上传了一个文件,也可以上传多个文件。

修改UploadAction,

private String username;

private String password;

private List<File> file;

private List<String> fileFileName;

private List<String> fileContentType;


重新生成set和get方法。

修改execute方法

public String execute() throws Exception {

for (int i = 0; i < file.size(); i++) {

InputStream is = new FileInputStream(file.get(i));

String path = ServletActionContext.getRequest().getRealPath(
"/upload");

OutputStream os = new FileOutputStream(new File(path, this
.getFileFileName().get(i)));

byte[] buffer = new byte[400];

int length = 0;

while ((length = is.read(buffer)) > 0) {

os.write(buffer, 0, length);

}

is.close();

os.close();
}

return SUCCESS;
}


然后修改upload页面。

在这里,可以有两种情况,一种是固定文件数目的上传,一种是动态的文件数目。

1.首先看看简单的,固定文件数目的上传。

修改upload.jsp中的表单

<s:form action="upload" method="post" enctype="multipart/form-data">

<s:textfield name="username" label="username"></s:textfield>

<s:password name="password" label="password"></s:password>

<s:file name="file" label="file1"></s:file>

<s:file name="file" label="file2"></s:file>

<s:file name="file" label="file3"></s:file>

<s:submit value=" submit "></s:submit>

</s:form>


注意<s:file>标签中的name要是一样的。

这样就可以上传固定数目的文件。

2.动态数目的文件上传。

这种动态性就是通过javascript来实现的,原理是对html进行DOM操作,实现动态地增加html标签。

首先新建upload2.jsp,将其theme设置为simple,然后使用表格对其布局。

<s:form action="upload" method="post" enctype="multipart/form-data" theme="simple">

<table width="50%">

<tr>

<td>username : </td>

<td>

<s:textfield name="username"></s:textfield>

</td>

</tr>

<tr>

<td>password : </td>

<td>

<s:password name="password"></s:password>

</td>

</tr>

<tr>

<td valign="top">file : </td>

<td id="more">

<s:file name="file"></s:file>

<input type="button" value=" Add More " onclick="addMore()" />

</td>

</tr>

<tr>

<td>

<s:submit value=" submit "></s:submit>

</td>

</tr>

</table>

</s:form>


然后的任务就是编写javascript代码,完成DOM操作

<mce:script type="text/javascript"><!--

function addMore(){

var td = document.getElementById("more");

var br = document.createElement("br");

var input = document.createElement("input");

input.type = "file";

input.name = "file";

var button = document.createElement("button");

button.value = "remove";

button.onclick = function(){

td.removeChild(br);

td.removeChild(input);

td.removeChild(button);
}

td.appendChild(br);

td.appendChild(input);

td.appendChild(button);
}

// --></mce:script>


关于这方面知识请阅读有关javascript方面的书籍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: