详解Java的Struts框架中上传文件和客户端验证的实现

时间:2022-04-11 01:38:34

文件上传

Struts 2框架提供了内置支持处理文件上传使用基于HTML表单的文件上传。上传一个文件时,它通常会被存储在一个临时目录中,他们应该由Action类进行处理或移动到一个永久的目录,以确保数据不丢失。

请注意,服务器有一个安全策略可能会禁止写到目录以外的临时目录和属于web应用的目录。

在Struts中的文件上传是通过预先定义的拦截文件上传拦截器这是可通过org.apache.struts2.interceptor.FileUploadInterceptor类的defaultStack中的一部分。仍然可以使用在struts.xml中设置各种参数,我们将在下面看到。

创建视图文件:
让我们开始创建我们认为这将需要浏览和上传选定的文件。因此,让我们创建一个纯HTML上传表单,允许用户上传文件 index.jsp:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%@ 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。这应该是设置为使得处理文件上传文件上传。下一个点值得注意的是表单的 action方法上传和文件上传字段的名称 - myFile。我们需要这些信息创建操作方法和struts配置。

接下来让我们创建一个简单的 jsp 文件的success.jsp 结果显示我们的文件上传的情况下成功。

?
1
2
3
4
5
6
7
8
9
10
<%@ 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 可能会有一些错误,在上传文件:

?
1
2
3
4
5
6
7
8
9
10
<%@ 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类:
接下来让我们创建一个Java类称为 uploadFile.java 这会处理上传文件,该文件存储在一个安全的位置:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.yiibai.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拦截器随着参数Intercetpor 确实为我们解决所有繁重工作。文件上传拦截器,使三个参数,默认情况下提供。它们被命名为以下模式:

[your file name parameter] - 这是实际的文件的上载。在这个例子中是 "myFile"

[your file name parameter]ContentType - 这是被上传的文件,该文件的内容类型。在这个例子中是 "myFileContentType"

[your file name parameter]FileName - 这是被上传的文件的名称。在这个例子中是 "myFileFileName"

这三个参数是为我们提供的,这要归功于Struts的拦截器。所有我们需要做的是在我们的Action类,这些变量是自动连线我们以正确的名称创建三个参数。所以,在上面的例子中,我们有三个参数的操作方法简单地返回“success”,如果一切顺利,否则返回“error”。

配置文件:
以下是Struts2的配置属性可以控制文件上传过程:

详解Java的Struts框架中上传文件和客户端验证的实现

为了改变这些设置,可以使用恒定的标签在应用程序 struts.xml文件,像我一样改变要上传的文件的最大大小。让我们有我们的在struts.xml如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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="com.yiibai.struts2.uploadFile">
    <result name="success">/success.jsp</result>
    <result name="error">/error.jsp</result>
  </action>
  </package>
</struts>

由于FileUpload拦截器是拦截器defaultStack的一部分,我们并不需要明确地配置。但可以添加<interceptor-ref>标签到<action>里面。文件上传拦截器需要两个参数:(a)maximumSize及(b)allowedTypes。maximumSize参数设置允许的最大文件大小(默认为约2MB)。allowedTypes参数接受的内容是一个逗号分隔的列表(MIME)类型,如下所示:

?
1
2
3
4
5
6
7
8
<action name="upload" class="com.yiibai.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文件中的内容:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?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文件。然后部署此WAR在Tomcat 的webapps目录下。最后,启动Tomcat服务器和尝试访问URL http://localhost:8080/HelloWorldStruts2/upload.jsp。这会给出以下画面:

详解Java的Struts框架中上传文件和客户端验证的实现

现在选择一个文件的“Contacts.txt”使用“浏览”按钮,然后点击上传按钮,将文件上传,应该看到页面。可以检查上传的文件保存在 C:apache-tomcat-6.0.33work.

详解Java的Struts框架中上传文件和客户端验证的实现

请注意,使用FileUpload拦截删除上传的文件自动所以需要编程在一些位置上保存上传的文件被删除之前。

错误消息:
fileUplaod拦截器使用几个默认的错误消息键:

详解Java的Struts框架中上传文件和客户端验证的实现

验证框架

现在,我们将看看如何的Struts验证框架。在Struts的核心有验证框架,协助应用程序的运行规则来执行验证执行之前的操作方法。

通常是使用Javascript来实现客户端验证。但不应单独依赖于客户端验证。最佳实践表明,验证应引入各级应用程序框架。现在,让我们来看看两种方式添加验证我们的Struts项目。

在这里,我们将采取一个例子,Employee 将被捕获的姓名和年龄使用一个简单的页面,我们将会把两个验证,以确保使用总是进入一个名字和年龄应该是在28和65之间。所以,让我们先从主JSP页面的例子。

创建主页面:
让我们写主JSP页面文件的index.jsp,这将被用来收集上述员工的相关信息。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<%@ 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>Employee Form</title>
</head>
 
<body>
  <s:form action="empinfo" method="post">
   <s:textfield name="name" label="Name" size="20" />
   <s:textfield name="age" label="Age" size="20" />
   <s:submit name="submit" label="Submit" align="center" />
  </s:form>
</body>
</html>

在index.jsp使用Struts的标签,我们还没有涉及,但我们将研究这些标签相关的章节。但现在,假设 s:textfield 标签打印一个输入字段s:submit打印一个提交按钮。我们已经使用label属性标签,每个标签每个标签创建。

创建视图:
我们将使用JSP文件的success.jsp将调用的情况下定义的动作返回SUCCESS。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<%@ 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>Success</title>
</head>
<body>
  Employee Information is captured successfully.
</body>
</html>

创建动作:
因此,让我们定义一个小小的动作类Employee,然后添加一个方法称为validate(),如下所示在Employee.java文件。请确保操作类扩展ActionSupport类,否则validate方法将不会被执行。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.yiibai.struts2;
 
import com.opensymphony.xwork2.ActionSupport;
 
public class Employee extends ActionSupport{
  private String name;
  private int age;
  
  public String execute()
  {
    return SUCCESS;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
 
  public void validate()
  {
   if (name == null || name.trim().equals(""))
   {
     addFieldError("name","The name is required");
   }
   if (age < 28 || age > 65)
   {
     addFieldError("age","Age must be in between 28 and 65");
   }
  }
}

如在上面的例子所示,“Name”字段的验证方法检查是否有一个值,或不。如果没有值已经提供,我们添加一个带有自定义错误消息“Age”字段的字段错误。其次,我们检查,如果输入的值是在28和65之间或不为“Age”字段,如果这个条件不符合我们以上验证字段添加一个错误。

配置文件:
最后,让我们把所有东西一起使用struts.xml的配置文件如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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" />
  <package name="helloworld" extends="struts-default">
 
   <action name="empinfo"
     class="com.yiibai.struts2.Employee"
     method="execute">
     <result name="input">/index.jsp</result>
     <result name="success">/success.jsp</result>
   </action>
 
  </package>
 
</struts>

以下是web.xml文件中的内容:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?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文件。然后部署此WAR在Tomcat的webapps目录下。最后,启动Tomcat服务器和尝试访问URL http://localhost:8080/HelloWorldStruts2/index.jsp。这会给出以下画面:

详解Java的Struts框架中上传文件和客户端验证的实现

现在不输入任何所需信息,只需点击“Submit ”按钮。将看到以下结果:

详解Java的Struts框架中上传文件和客户端验证的实现

输入所需的信息,但输入了错误的From字段,让我们说“test”和年龄为30,最后点击“Submit ”按钮。将看到以下结果:

详解Java的Struts框架中上传文件和客户端验证的实现

此验证是如何工作的?
当用户按下提交按钮时,Struts2会自动执行的验证方法,如果任何一个if语句里面的方法列出,Struts 2调用addFieldError方法。如果有任何错误已加入Struts 2将不会进行调用execute方法。而Struts 2框架将返回输入作为调用该行动的结果。

因此,验证失败时Struts2返回输入,Struts 2框架将重新显示index.jsp文件。因为我们使用了Struts 2的表单标签,Struts2中会自动添加错误消息,只是上面的形式提交。

这些错误消息是我们addFieldError方法调用中指定的。addFieldError方法有两个参数。首先是表单字段名错误,第二个是错误信息,上面显示该表单字段。

?
1
addFieldError("name","The name is required");

要处理的返回值输入,我们需要添加以下的结果,以我们的动作节点在struts.xml。

?
1
<result name="input">/index.jsp</result>

基于XML的验证:
在进行验证的第二个方法是通过将一个xml文件的动作类。Struts2的基于XML验证的验证提供了更多的选择,如电子邮件验证,整数范围验证,表单验证字段,表达式验证,正则表达式验证,需要验证,验证所需的字符串,字符串长度的验证等。

XML文件需要被命名为'[action-class]'-validation.xml。所以,在我们的例子中,我们创建一个文件,名为 Employee-validation.xml包含以下内容:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
 
<validators>
  <field name="name">
   <field-validator type="required">
     <message>
      The name is required.
     </message>
   </field-validator>
  </field>
 
  <field name="age">
   <field-validator type="int">
     <param name="min">29</param>
     <param name="max">64</param>
     <message>
      Age must be in between 28 and 65
     </message>
   </field-validator>
  </field>
</validators>

上面的XML文件会被保存在CLASSPATH 沿着类文件。让我们有我们的雇员动作类没有validate()方法如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.yiibai.struts2;
 
import com.opensymphony.xwork2.ActionSupport;
 
public class Employee extends ActionSupport{
  private String name;
  private int age;
  
  public String execute()
  {
    return SUCCESS;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
}

其余的设置将保持,因为它是我前面的例子,现在,如果运行应用程序,它会产生相同的结果是什么,我们在前面的例子:

xml文件来存储配置的优点是允许的验证从应用程序代码的分离。可以让开发人员编写的代码和业务分析师建立验证xml文件。要注意的是另一件事是默认提供的验证类型。有大量的验证,默认情况下,使用Struts。常见的验证包括验证日期,正则表达式验证字符串长度的验证。检查以下链接更多细节 Struts - 基于XML的校验.