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

struts2上传文件(Common-FileUpload)

2017-02-02 22:39 399 查看


1.准备工作。

Struts2,默认使用的就是Common-FileUpload的文件上传框架,想要使用这个框架的话,需要将两个JAR文件导入到项目中,分别是:commons-io-2.4.jar和commons-fileupload-1.3.2.jar(将这两个包复制到WEB-INF\lib路径下)。



导入完所需要的JAR包之后,就可以使用该框架进行文件的上传工作。

2.表单的支持。

在表单中需要指定enctype属性为:multipart/form-data。

其他的属性可以见:http://www.zgguan.com/doc/w3c/tags/att_form_enctype.asp.htm

所以使用struts2所编写的JSP文件代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:form action="upload" enctype="multipart/form-data">
<s:file name="upload" label="ChooseFile"></s:file>
<s:submit value="Submit"></s:submit>
</s:form>
</body>
</html>


这里使用了struts2中的s标签。也可以单纯的是用html表单,但是method方法需要设置为:post。

<form action="upload.action" enctype="multipart/form-data" method="post">
选择文件:<input type="file" name="upload">
<input type="submit" value="Submit">
</form>


3.Action处理文件。

如果表单的部分设置完成之后,那么下一步就是需要对上传过来的文件进行接收保存之类的处理了。
建立一个Action,处理文件的部分如下:
package hellostruts;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Set;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class upload extends ActionSupport {
private String title;
private File upload;
private String uploadContentType;
private String uploadFileName;
private String savePath;

public void setSavePath(String value) {
this.savePath = value;
}

private String getSavePath() throws Exception {
return "F:\\file";
}

public void setUpload(File upload) {
this.upload = upload;
}

public File getUpload() {
return this.upload;
}

public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}

public String getUploadContentType() {
return this.uploadContentType;
}

public void setUploadFileName(String uploadName) {
this.uploadFileName = uploadName;
}

public String getUploadFileName() {
return this.uploadFileName;
}

@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
FileOutputStream fileOutputStream = new FileOutputStream(getSavePath() + "\\" + getUploadFileName());
System.out.print(getUploadContentType() + getUploadFileName());
FileInputStream fileInputStream = new FileInputStream(getUpload());
byte[] buffer = new byte[1024];
int len = 0;
while((len = fileInputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer,0,len);
}
return SUCCESS;
}

}


这里的setter和getter都是一般Action中所必须包含的内容。
其中的setSavePath方法,是从struts.xml中或许参数值的(这里并没有什么用。。。因为getSavePath中直接返回了“F:\\file”)。
其他三对setter和getter方法都有特定的格式:

如果表单中包含一个name属性为xxx的文件域,那么对应的Action需要使用三个成员变量来封装该文件域的信息:
类型为File的xxx成员变量封装了该文件域对应的文件内容。(就是上述的setUpload(File upload)方法和getUpload()方法)。
类型为String的xxxFileName成员变量封装了该文件域对应的文件的文件类名。(就是上述的setUploadFileName(String uploadName)和getUploadFileName()方法)。
类型为String的xxxContentType成员变量封装了该文件域对应的文件类型。(就是上述的setUploadContentType(String uploadContentType)和getUploadContentType()方法)。

当有文件上传时,会自动的调用这个setter方法进行设置。

然后再execute中调用相关方法对文件进行保存操作即可。

然后配置struts.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<include file="struts-default.xml"></include>
<!-- 指定默认编码集 -->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<!-- 指定需要Struts2处理的请求后缀 -->
<constant name="struts.action.extension" value="do,action"></constant>
<!-- 设置浏览器是否缓存静态内容,开发阶段应关闭,生产阶段打开,默认为打开 -->
<constant name="struts.serve.static.browserCache" value="false"></constant>
<!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认为false,开发阶段应打开 -->
<constant name="struts.configuration.xml.reload" value="true"></constant>
<!-- 开发模式下使用,可以打印出更详细的错误信息 -->
<constant name="struts.devMode" value="true"></constant>
<!-- action全部用注解进行配置 -->

<!-- 是否开启动态方法调用 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<!--添加包 -->
<package name="hellostruts" extends="struts-default">
<action name="upload" class="hellostruts.upload">
<result>success.jsp</result>
</action>
</package>

</struts>


测试结果:

选择一个txt文件测试。



点击上传。



可以在相对应的路径下面看到该文件已经成功上传保存,如果文件过大的话可能上传失败。。。

4.拦截部分文件。

1.自定义方法拦截。

顾名思义,就是自己写一个方法,然后在里面写一些支持上传的文件的类型等信息,然后调用该方法来检测所上传的文件是否合法。

例子:

在上述例子中,加入了一个新的String类型的变量用来检测所上传文件类型是否合法。

private String allowTypes;

public void setAllowTypes(String allowTypes) {
this.allowTypes = allowTypes;
}

public String getAllowTypes() {
return this.allowTypes;
}


这里的setAllowTypes直接从struts.xml中获取参数变量。

所以这里的struts.xml中对应的action内容为:

<action name="upload" class="hellostruts.upload">
<param name="allowTypes">text/plain,img</param>
<result>success.jsp</result>
<result name="input">error.jsp</result>
</action>


添加一个param标签,name属性设置为String变量的名字,后面的参数就是该变量的值,会自动调用setter方法的。

然后编写一个自定义拦截方法:

public String filterTypes(String[] types) {
String filtType = getUploadContentType();
System.out.print(filtType);
for(String type : types) {
if(type.equals(filtType)) {
return null;
}
}
return ERROR;
}

@Override
public void validate() {
String filterResult = filterTypes(getAllowTypes().split(","));
if (filterResult != null) {
addFieldError("upload", "该文件格式不支持上传!");
}
}


filterTypes方法可以对上传进来的文件类型进行检测,如果不符合要求的话,就添加提示错误信息,因为使用了validate方法进行校验,所以如果校验失败的话会返回字符串“input”,所以需要在struts.xml中的结果里面配置一个input试图。

测试:

如果选择一个txt文本本件的话,可以上传,因为在

<param name="allowTypes">text/plain,img</param>
中指定了text/plain的格式,但是如果选择一个.png格式的文件进行上传的话,就不能够进行。



点击提交之后:



这里使用了error.jsp中的

<s:fielderror>
<s:param>upload</s:param>
</s:fielderror>

进行输出提示信息。

2.拦截器实现文件过滤。

可以使用fileUpload拦截器进行拦截文件。

拦截器实现文件过滤的话,只需要在Action中配置该拦截器的引用即可,配置fileUpload时,可以为其指定两个参数:

allowedTypes:该参数指定允许上传的文件类型,多个文件类型之间以英文逗号(,)隔开。

maximumSize:该参数指定允许上传的文件大小,单位是字符。

需要注意的是:

当文件过滤失败后,系统会自动的转入input逻辑视图,所以需要为该Action配置名为input的逻辑视图。此外,还必须显式地为该Action配置defaultStack的拦截器引用。

所以,如果想实现刚才自定义拦截器中的功能的话,可以在struts.xml中将action的配置修改为:

<action name="upload" class="hellostruts.upload">
<interceptor-ref name="fileUpload">
<param name="allowedTypes">text/plain,img</param>
<param name="maximumSize">20000</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
<result>success.jsp</result>
<result name="input">error.jsp</result>
</action>


这样的话,就可以省略掉刚才所编写的自定义过滤文件的方法,但是能够达到相同的目的,可以看出这样使用拦截器实现文件过滤的话比较简单,但在某些情况下使用自定义方法进行过滤比较合适。

测试:

同样的,这里只支持text/plain的格式,如果想要上传其他格式的话,会在<fielderror>标签中显示如下内容:



如果上传的文件大小过大的话,会提示如下内容:



如果有什么错误的地方,希望大家能够指出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: