Java的Struts框架中Action的编写与拦截器的使用方法

Struts2 Action/动作
动作是Struts2框架的核心,因为他们的任何MVC(模型 - 视图 - 控制器)框架。每个URL将被映射到一个特定的动作,它提供了来自用户的请求提供服务所需的处理逻辑。

但动作也提供其他两个重要的能力。首先,操作从请求数据的传输中起着重要的作用,通过向视图,无论是一个JSP或其它类型的结果。二,动作必须协助的框架,在确定结果应该渲染视图,在响应该请求将被退回。

创建动作:
在Struts2的动作,唯一的要求是必须有一个无参数的方法返回String或结果的对象,必须是一个POJO。如果不带参数的方法是不指定,则默认动作是使用execute()方法。

也可以选择扩展ActionSupport类实现了6个接口,包括动作界面。动作界面如下:

public interface Action {
 public static final String SUCCESS = "success";
 public static final String NONE = "none";
 public static final String ERROR = "error";
 public static final String INPUT = "input";
 public static final String LOGIN = "login";
 public String execute() throws Exception;
}

让我们来看看Hello World示例的操作方法:

package com.yiibai.struts2;

public class HelloWorldAction{
 private String name;

 public String execute() throws Exception {
  return "success";
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
}

为了说明这一点,操作方法控制视图,让我们做出以下更改执行方法和扩展类ActionSupport 如下:

package com.yiibai.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport{
 private String name;

 public String execute() throws Exception {
  if ("SECRET".equals(name))
  {
   return SUCCESS;
  }else{
   return ERROR;
  }
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
}

在这个例子中,我们有一些在execute方法的逻辑来看待的name属性。如果属性等于字符串“SECRET”,我们返回SUCCESS 的结果,否则我们返回ERROR 的结果。因为我们已经扩展ActionSupport,所以我们可以使用字符串常量的成功和错误。现在,让我们修改我们的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" />
  <package name="helloworld" extends="struts-default">
   <action name="hello"
   class="com.yiibai.struts2.HelloWorldAction"
   method="execute">
   <result name="success">/HelloWorld.jsp</result>
   <result name="error">/AccessDenied.jsp</result>
   </action>
  </package>
</struts>

创建视图
让我们创建以下JSP文件 helloWorld.jsp 的WebContent文件夹在eclipse项目。要做到这一点,右键单击WebContent文件夹在项目资源管理器,选择New >JSP File。该文件将要求返回的结果是SUCCESS,这是一个字符串常量“success”的定义在动作界面:

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Hello World</title>
</head>
<body>
 Hello World, <s:property value="name"/>
</body>
</html>

以下是由框架的动作的结果将被调用的文件,该文件是等于字符串常量“错误”的ERROR 。以下是AccessDenied.jsp 的内容

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Access Denied</title>
</head>
<body>
 You are not authorized to view this page.
</body>
</html>

我们还需要在WebContent文件夹中创建index.jsp。该文件将作为初始动作URL,用户可以直接点击告诉Struts 2框架调用HelloWorldAction类的 execute方法,并呈现 helloWorld.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>Hello World</title>
</head>
<body>
 <h1>Hello World From Struts2</h1>
 <form action="hello">
  <label for="name">Please enter your name</label><br/>
  <input type="text" name="name"/>
  <input type="submit" value="Say Hello"/>
 </form>
</body>
</html>

就是这样,不需要改变的web.xml文件,所以让我们用同一个web.xml,是之前我们已经创建了范例章。现在,我们已经准备好运行使用Struts 2框架的 Hello World应用程序。

执行应用程序
右键点击项目名称,并单击 Export > WAR File 创建一个WAR文件。然后在Tomcat 的webapps目录下部署这个WAR。最后,启动Tomcat服务器和尝试访问URL http://localhost:8080/HelloWorldStruts2/index.jsp。这会给出以下画面:

让我们为“SECRET”,并输入一个字,应该看到以下页面:

现在输入任何单词而非“SECRET”,应该看到以下页面:

建立多个动作:
经常会定义一个以上的动作,以处理不同的请求,并提供不同的用户的URL,因此可以定义不同的类定义如下:

package com.yiibai.struts2;
import com.opensymphony.xwork2.ActionSupport;

 class MyAction extends ActionSupport{
  public static String GOOD = SUCCESS;
  public static String BAD = ERROR;
 }

 public class HelloWorld extends ActionSupport{
  ...
  public String execute()
  {
   if ("SECRET".equals(name)) return MyAction.GOOD;
   return MyAction.BAD;
  }
  ...
 }

 public class SomeOtherClass extends ActionSupport{
  ...
  public String execute()
  {
   return MyAction.GOOD;
  }
  ...
 }

在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" />
 <package name="helloworld" extends="struts-default">
  <action name="hello"
   class="com.yiibai.struts2.HelloWorld"
   method="execute">
   <result name="success">/HelloWorld.jsp</result>
   <result name="error">/AccessDenied.jsp</result>
  </action>
  <action name="something"
   class="com.yiibai.struts2.SomeOtherClass"
   method="execute">
   <result name="success">/Something.jsp</result>
   <result name="error">/AccessDenied.jsp</result>
  </action>
 </package>
</struts>

正如看到在上述假设的例子,动作的结果是重复的SUCCESS和ERROR。要解决这个问题,建议创建一个类包含结果的结果。

Struts2 拦截器
拦截器的概念是Servlet过滤器或JDK代理类一样的。拦截器允许横切功能分开实现的动作,以及框架。使用拦截器,可以实现如下:

  • 提供预处理行动之前被称为逻辑。
  • 提供后处理逻辑动作后被调用
  • 捕获异常,这样可以进行替代处理。

Struts2框架提供的许多功能都使用拦截实现的例子包括异常处理,文件上传,生命周期回调和验证等事实上作为Struts2的基础,其功能拦截,这可能有7或8拦截器分配给每个动作。

Struts2框架的拦截器:
Struts 2框架提供了良好的箱拦截列表来预先设定的,并准备使用。下面列出了几个重要的拦截:

请看Struts 2文档的完整细节上面提到的拦截。会告诉如何使用Struts应用程序在一个拦截器。

如何使用拦截器?
让我们来看看如何使用已有的拦截,我们的“Hello World”程序。我们将使用计时器来测量过了多长时间执行操作方法,其目的是拦截。同时使用params拦截器,其目的是发送请求参数的动作。您可以尝试不使用这个拦截您的示例中会发现,没有被设置name属性,因为参数是无法达到动作。

我们将继续HelloWorldAction.java,web.xml 的helloWorld.jsp 和 index.jsp 文件,因为他们已经建立了范例章节,但让我们如下修改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" />
 <package name="helloworld" extends="struts-default">
  <action name="hello"
   class="com.yiibai.struts2.HelloWorldAction"
   method="execute">
   <interceptor-ref name="params"/>
   <interceptor-ref name="timer" />
   <result name="success">/HelloWorld.jsp</result>
  </action>
 </package>
</struts>

右键点击项目名称,并单击 Export > WAR File 创建一个WAR文件。然后部署在Tomcat 的webapps目录下这个WAR。最后,启动Tomcat服务器和尝试访问URL http://localhost:8080/HelloWorldStruts2/index.jsp。这会给你以下画面:

现在,在给定的文本框中输入单词,并单击“Say Hello按钮执行已定义的动作。现在,如果将检查生成的日志,会发现下面的文字:

INFO: Server startup in 3539 ms
27/08/2011 8:40:53 PM
com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Executed action [//hello!execute] took 109 ms.

这里底行,正在生成因为这告诉动作发生要执行的总共为 109ms定时器的拦截器。

创建自定义的拦截器
在应用程序中使用自定义的拦截器是一种优雅的方式提供横切的应用功能。创建一个自定义拦截器是很容易的,需要扩展的接口,下面的Interceptor接口:

public interface Interceptor extends Serializable{
 void destroy();
 void init();
 String intercept(ActionInvocation invocation)
 throws Exception;
}

正如其名称所表明的,init()方法提供了一种方法来初始化拦截器,并destroy() 方法提供了一种工具拦截清理。不同的行动,拦截被重用跨请求和需要是线程安全的,尤其是intercept() 方法。

ActionInvocation对象可以访问运行时环境。它允许访问的动作本身和方法调用的动作,并确定动作是否已被调用。

如果不需要初始化或清除代码,可以扩展AbstractInterceptor类。这提供了一个默认的无操作实现的init()和 destroy()方法。

创建拦截器类:
让我们创建Java资源 MyInterceptor.java> src 文件夹:

package com.yiibai.struts2;

import java.util.*;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class MyInterceptor extends AbstractInterceptor {

 public String intercept(ActionInvocation invocation)throws Exception{

  /* let us do some pre-processing */
  String output = "Pre-Processing";
  System.out.println(output);

  /* let us call action or next interceptor */
  String result = invocation.invoke();

  /* let us do some post-processing */
  output = "Post-Processing";
  System.out.println(output);

  return result;
 }
}

就像看到的,实际行动将使用拦截器执行invocation.invoke()调用。所以,可以做一些前处理和一些处理后,根据需要。

该框架本身启动的过程中,在第一次调用ActionInvocation对象的invoke()。每次 invoke()被调用,ActionInvocation的咨询的状态和执行为准拦截接下来。通过请求流以下数据图显示了相同的概念:

创建动作类:
让我们创建一个Java文件HelloWorldAction.java的Java下Java Resources > src下面给出的内容包名为 com.yiibai.struts2。

package com.yiibai.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport{
 private String name;

 public String execute() throws Exception {
  System.out.println("Inside action....");
  return "success";
 } 

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
}

在前面的例子中,我们已经看到,这是一个相同的类。我们有标准的“名称”属性的getter和setter方法​​,并返回字符串“success”的执行方法。

创建视图
让我们创建以下JSP文件helloWorld.jsp,在eclipse项目在WebContent文件夹。

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Hello World</title>
</head>
<body>
 Hello World, <s:property value="name"/>
</body>
</html>

创建页面:
我们还需要在WebContent文件夹中创建 index.jsp。该文件将作为初始动作URL,用户可以在其中点击告诉Struts 2框架调用 HelloWorldAction类定义的方法呈现 helloWorld.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>Hello World</title>
</head>
<body>
 <h1>Hello World From Struts2</h1>
 <form action="hello">
  <label for="name">Please enter your name</label><br/>
  <input type="text" name="name"/>
  <input type="submit" value="Say Hello"/>
 </form>
</body>
</html>

Hello 动作定义在上面的视图文件将被映射到HelloWorldAction类和其执行方法使用struts.xml文件。

配置文件
现在,我们需要注册我们的拦截器,然后调用它默认的拦截器在前面的例子中调用。要注册一个新定义的拦截,直接放在的<interceptors>...</interceptors>标签下<package>的标签插件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" />
 <package name="helloworld" extends="struts-default">

  <interceptors>
   <interceptor name="myinterceptor"
   class="com.yiibai.struts2.MyInterceptor" />
  </interceptors>

  <action name="hello"
   class="com.yiibai.struts2.HelloWorldAction"
   method="execute">
   <interceptor-ref name="params"/>
   <interceptor-ref name="myinterceptor" />
   <result name="success">/HelloWorld.jsp</result>
  </action>

 </package>
</struts>

应该指出的是,可以注册多个拦截器<package>标签内,同一时间,可以调用多个拦截里面的<action>标签。可以调用相同的拦截器与不同的动作。

web.xml文件需要在 WEB-INF文件夹下创建 WebContent 如下:

<?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/index.jsp。这会给你以下画面:

现在,在给定的文本框中输入任何单词,并单击“Say Hello“ 按钮执行已定义的动作。现在,如果检查生成的日志,会发现下面的文本下方:

Pre-Processing
Inside action....
Post-Processing

堆叠多个拦截器:
可以想像,配置多个拦截器每个动作很快就会变得非常难以控制。出于这个原因,拦截器与拦截器栈管理。下面是一个例子,直接从在struts-default.xml文件:

<interceptor-stack name="basicStack">
 <interceptor-ref name="exception"/>
 <interceptor-ref name="servlet-config"/>
 <interceptor-ref name="prepare"/>
 <interceptor-ref name="checkbox"/>
 <interceptor-ref name="params"/>
 <interceptor-ref name="conversionError"/>
</interceptor-stack>

上面的栈被调用basicStack,可用于在配置中,如下所示。此配置节点放置在<package.../>节点下。每个<interceptor-ref.../>标记引用一个拦截器或拦截器栈已配置在当前的拦截器栈。因此,这是非常重要的,以确保该名称是唯一的所有拦截器和拦截器栈配置配置初始的拦截器和拦截器栈时。

我们已经看到了如何应用拦截的动作,将拦截器栈是没有什么不同。事实上,我们完全使用相同的标签:

<action name="hello" class="com.yiibai.struts2.MyAction">
 <interceptor-ref name="basicStack"/>
 <result>view.jsp</result>
</action

上述注册的“basicStack”所有6个拦截器完成注册的栈 Hello 动作。应该指出的是,拦截器执行的顺序在配置中。例如,在上述情况下,异常将被执行,servlet 配置等。

(0)

相关推荐

  • Struts中action线程安全问题解析

    [问题描述] 最近公司安排我面试Java的FreshMan,面试者一般是工作1年多点的新人(这里我就装老一下,其实我也才工作3年不到),在被问及Struts1和Struts2的Action的线程安全问题的时候,大多是支支吾吾,答不出所以然.所以在这里我整理一下我个人的理解. [问题答案] 这是由于Servlet的工作原理产生的.我们先来简单回顾一下Servlet的生命周期"初始化->init->service->destroy->卸载". 这里大家都知道,我们在

  • 深入解析Java的Struts框架中的控制器DispatchAction

    Struts中的表单处理器为ActionForm,而struts中的控制器主要是Action,以及DispatchAction控制器等. Action 在struts中,所有的用户都会经过ActionServlet的处理,而实际的工作是交给Action对象来处理的,ActionServlet可以从配置文件中创建ActionMapping对象,从ActionMapping对象中找到对应使用的Action,然后将用户请求转交给Action. 对Struts一个ActionMapping只能生成一个A

  • 详解在Java的Struts2框架中配置Action的方法

    在Struts2中Action部分,也就是Controller层采用了低侵入的方式.为什么这么说?这是因为在Struts2中action类并不需要继承任何的基类,或实现任何的接口,更没有与Servlet的API直接耦合.它通常更像一个普通的POJO(通常应该包含一个无参数的execute方法),而且可以在内容定义一系列的方法(无参方法),并可以通过配置的方式,把每一个方法都当作一个独立的action来使用,从而实现代码复用. 例如: package example; public class U

  • Java的Struts框架中Action的编写与拦截器的使用方法

    Struts2 Action/动作 动作是Struts2框架的核心,因为他们的任何MVC(模型 - 视图 - 控制器)框架.每个URL将被映射到一个特定的动作,它提供了来自用户的请求提供服务所需的处理逻辑. 但动作也提供其他两个重要的能力.首先,操作从请求数据的传输中起着重要的作用,通过向视图,无论是一个JSP或其它类型的结果.二,动作必须协助的框架,在确定结果应该渲染视图,在响应该请求将被退回. 创建动作: 在Struts2的动作,唯一的要求是必须有一个无参数的方法返回String或结果的对象

  • Java下Struts框架中的ActionForm类详解

    ActionForm的应用 (1) .创建一个form类必须继承四个父类中的一个.比如继承ActionForm. (2) .一个form类中的每一个属性都将和页面中form 表单中的每一个元素一一对应 例如. 一个表单为: <form> <input type="text" name="username"></input> <input type="password" name="passwor

  • Java的Struts框架中登陆功能的实现和表单处理器的使用

    实现Struts登录 1.jar包拷贝 首先是建立java web项目,之后打开我们我们下载好strtus框架,Struts-1.2.9-bin文件夹和struts-1.2.9.src源文件文件夹.在bin文件夹中的lib文件中拷贝struts的jar包,拷贝到我们自己项目struts_login –>lib文件夹下. 2.web.xml文件配置 找到Struts-1.2.9-bin中Struts-1.2.9-bin-->webapps下的struts实例struts-blank中的strut

  • Java的Struts框架中的主题模板和国际化设置

    主题模板 如果不指定一个主题,然后Struts2中会使用默认的XHTML主题.例如Struts 2中选择标签: <s:textfield name="name" label="Name" /> 生成HTML标记: <tr> <td class="tdLabel"> <label for="empinfo_name" class="label">Name:<

  • Java的Struts框架中<results>标签的使用方法

    <results>标签在Struts2的MVC框架的视图中所扮演的角色.动作是负责执行业务逻辑.执行业务逻辑后,接下来的步骤是使用<results>标签显示的视图. 经常有一些附带导航规则的结果.例如,如果在操作方法是对用户进行验证,有三种可能的结果. (一)成功登录:(二)不成功的登录,用户名或密码错误:(三)帐户锁定. 在这种情况下的动作方法将被配置呈现的结果有三种可能的结果字符串和三个不同的看法.我们已经看到在前面的例子. 但是,Struts2 不配合使用JSP作为视图技术.

  • 简单说明Java的Struts框架中merge标签的使用方法

    merge标签合并标记需要两个或两个以上的列表作为参数,并把它们合并在一起,如下所示: <s:merge var="myMergedIterator"> <s:param value="%{myList1}" /> <s:param value="%{myList2}" /> <s:param value="%{myList3}" /> </s:merge> <

  • 在Java的Struts框架中ONGL表达式的基础使用入门

    首先了解下OGNL的概念: OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对象的方法,能够遍历整个对象的结构图,实现对象属性类型的转换等功能. 此外,还得先需弄懂OGNL的一些知识: 1.OGNL表达式的计算是围绕OGNL上下文进行的. OGNL上下文实际上就是一个Map对象,由ognl.OgnlContext类表示.它里面可以存放很多个JavaBean对象.

  • 详解Java的Struts框架中栈值和OGNL的使用

    值栈: 值栈是一个集合中的几个对象保持下列对象提供的顺序: 值栈可以通过JSP,Velocity或者Freemarker的标签.有各种不同的标签在单独的章节中,我们将学习,用于获取和设置Struts 2.0 的值栈. ValueStack的对象里面可以得到动作如下: ActionContext.getContext().getValueStack() 一旦拥有了值对象,就可以用下面的方法来操纵该对象: OGNL: 对象图形导航语言(OGNL)是一个功能强大的表达式语言是用来参考值栈上的数据和操纵

  • Java的Struts框架中append标签与generator标签的使用

    append 标签: 这些append标签需要两个或两个以上的列表作为参数,并追加它们放在一起,如下图所示: <s:append var="myAppendIterator"> <s:param value="%{myList1}" /> <s:param value="%{myList2}" /> <s:param value="%{myList3}" /> </s:ap

随机推荐