文件上传(File Uploads)
Struts 2框架使用“基于表单的HTML文件上载”为处理文件上载提供内置支持。 上传文件时,它通常会存储在临时目录中,并且应由Action类处理或移动它们到永久目录,以确保数据不会丢失。
Note - 服务器可能具有安全策略,禁止您写入临时目录以外的目录以及属于Web应用程序的目录。
可以通过名为FileUpload拦截器的预定义拦截器在Struts中上传文件,该拦截器可通过org.apache.struts2.interceptor.FileUploadInterceptor类获得,并作为defaultStack一部分包含在内。 仍然可以在struts.xml中使用它来设置各种参数,我们将在下面看到。
创建视图文件
让我们从创建浏览和上传所选文件所需的视图开始。 因此,让我们使用纯HTML上传表单创建一个index.jsp ,允许用户上传文件 -
<%@ page language = "java" contentType = "text/html; charset = ISO-8859-1"
pageEncoding = "ISO-8859-1"%>
<%@ taglib prefix = "s" uri = "/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>File Upload</title>
</head>
<body>
<form action = "upload" method = "post" enctype = "multipart/form-data">
<label for = "myFile">Upload your file</label>
<input type = "file" name = "myFile" />
<input type = "submit" value = "Upload"/>
</form>
</body>
</html>
在上面的例子中有几点值得注意。 首先,表单的enctype设置为multipart/form-data 。 应设置此选项,以便文件上载拦截器成功处理文件上载。 下一点需要注意的是表单的操作方法upload和文件上载字段的名称 - 即myFile 。 我们需要此信息来创建操作方法和struts配置。
接下来,让我们创建一个简单的jsp文件success.jsp ,以便在success.jsp时显示文件上传的结果。
<%@ page contentType = "text/html; charset = UTF-8" %>
<%@ taglib prefix = "s" uri = "/struts-tags" %>
<html>
<head>
<title>File Upload Success</title>
</head>
<body>
You have successfully uploaded <s:property value = "myFileFileName"/>
</body>
</html>
以下将是结果文件error.jsp ,以防上传文件时出现一些错误 -
<%@ page contentType = "text/html; charset = UTF-8" %>
<%@ taglib prefix = "s" uri = "/struts-tags" %>
<html>
<head>
<title>File Upload Error</title>
</head>
<body>
There has been an error in uploading the file.
</body>
</html>
创建Action类 (Create Action Class)
接下来,让我们创建一个名为uploadFile.java的Java类,它将负责上传文件并将该文件存储在安全的位置 -
package cn.xnip.struts2;
import java.io.File;
import org.apache.commons.io.FileUtils;
import java.io.IOException;
import com.opensymphony.xwork2.ActionSupport;
public class uploadFile extends ActionSupport {
private File myFile;
private String myFileContentType;
private String myFileFileName;
private String destPath;
public String execute() {
/* Copy file to a safe location */
destPath = "C:/apache-tomcat-6.0.33/work/";
try {
System.out.println("Src File name: " + myFile);
System.out.println("Dst File name: " + myFileFileName);
File destFile = new File(destPath, myFileFileName);
FileUtils.copyFile(myFile, destFile);
} catch(IOException e) {
e.printStackTrace();
return ERROR;
}
return SUCCESS;
}
public File getMyFile() {
return myFile;
}
public void setMyFile(File myFile) {
this.myFile = myFile;
}
public String getMyFileContentType() {
return myFileContentType;
}
public void setMyFileContentType(String myFileContentType) {
this.myFileContentType = myFileContentType;
}
public String getMyFileFileName() {
return myFileFileName;
}
public void setMyFileFileName(String myFileFileName) {
this.myFileFileName = myFileFileName;
}
}
uploadFile.java是一个非常简单的类。 需要注意的重要一点是FileUpload拦截器和参数拦截器为我们做了所有繁重的工作。
默认情况下,FileUpload拦截器为您提供三个参数。 它们以下列模式命名 -
[your file name parameter] - 这是用户上传的实际文件。 在这个例子中它将是“myFile”
[your file name parameter]ContentType - 这是上载文件的内容类型。 在这个例子中它将是“myFileContentType”
[your file name parameter]FileName - 这是上载文件的名称。 在这个例子中它将是“myFileFileName”
由于Struts拦截器,我们可以使用这三个参数。 我们所要做的就是在Action类中使用正确的名称创建三个参数,并自动为这些变量自动连接。 所以,在上面的例子中,我们有三个参数和一个动作方法,如果一切正常,它只返回“成功”,否则返回“错误”。
配置文件 (Configuration Files)
以下是控制文件上载过程的Struts2配置属性 -
Sr.No | 属性和描述 |
---|---|
1 | struts.multipart.maxSize 要接受为文件上载的文件的最大大小(以字节为单位)。 默认值为250M。 |
2 | struts.multipart.parser 用于上传多部分表单的库。 默认情况下是jakarta |
3 | struts.multipart.saveDir 存储临时文件的位置。 默认情况下是javax.servlet.context.tempdir。 |
为了更改任何这些设置,您可以在应用程序struts.xml文件中使用constant标记,就像我更改要上载的文件的最大大小一样。
让我们将struts.xml如下 -
<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name = "struts.devMode" value = "true" />
<constant name = "struts.multipart.maxSize" value = "1000000" />
<package name = "helloworld" extends = "struts-default">
<action name = "upload" class = "cn.xnip.struts2.uploadFile">
<result name = "success">/success.jsp</result>
<result name = "error">/error.jsp</result>
</action>
</package>
</struts>
因为, FileUpload拦截器是默认的拦截器堆栈的一部分,所以我们不需要明确配置它。 但是,您可以在“action”中添加“interceptor-ref”标记。 fileUpload拦截器有两个参数(a) maximumSize和(b) allowedTypes 。
maximumSize参数设置允许的最大文件大小(默认值约为2MB)。 allowedTypes参数是以逗号分隔的接受内容(MIME)类型列表,如下所示 -
<action name = "upload" class = "cn.xnip.struts2.uploadFile">
<interceptor-ref name = "basicStack">
<interceptor-ref name = "fileUpload">
<param name = "allowedTypes">image/jpeg,image/gif</param>
</interceptor-ref>
<result name = "success">/success.jsp</result>
<result name = "error">/error.jsp</result>
</action>
以下是web.xml文件的内容 -
<?xml version = "1.0" Encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns = "http://java.sun.com/xml/ns/javaee"
xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id = "WebApp_ID" version = "3.0">
<display-name>Struts 2</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
现在右键单击项目名称,然后单击“ Export 》 WAR File以创建War文件。 然后在Tomcat的webapps目录中部署此WAR。 最后,启动Tomcat服务器并尝试访问URL http://localhost:8080/HelloWorldStruts2/upload.jsp 。 这将产生以下屏幕 -
现在使用“浏览”按钮选择文件“Contacts.txt”,然后单击“上传”按钮,该按钮将在您的服务上传文件,您应该会看到下一页。 您可以检查上传的文件是否应保存在C:\apache-tomcat-6.0.33\work中。
请注意,FileUpload Interceptor会自动删除上载的文件,因此您必须在删除之前在某个位置以编程方式保存上载的文件。
错误消息
fileUplaod拦截器使用几个默认的错误消息密钥 -
Sr.No | 错误消息密钥和描述 |
---|---|
1 | struts.messages.error.uploading 无法上载文件时发生的一般错误。 |
2 | struts.messages.error.file.too.large 当上载的文件太大而不是maximumSize指定时发生。 |
3 | struts.messages.error.content.type.not.allowed 当上载的文件与指定的预期内容类型不匹配时发生。 |
您可以在WebContent/WEB-INF/classes/messages.properties资源文件中覆盖这些消息的文本。