Java的Struts框架中Action的編寫與攔截器的使用方法
Struts2 Action/動(dòng)作
動(dòng)作是Struts2框架的核心,因?yàn)樗麄兊娜魏蜯VC(模型 - 視圖 - 控制器)框架。每個(gè)URL將被映射到一個(gè)特定的動(dòng)作,它提供了來自用戶的請(qǐng)求提供服務(wù)所需的處理邏輯。
但動(dòng)作也提供其他兩個(gè)重要的能力。首先,操作從請(qǐng)求數(shù)據(jù)的傳輸中起著重要的作用,通過向視圖,無(wú)論是一個(gè)JSP或其它類型的結(jié)果。二,動(dòng)作必須協(xié)助的框架,在確定結(jié)果應(yīng)該渲染視圖,在響應(yīng)該請(qǐng)求將被退回。
創(chuàng)建動(dòng)作:
在Struts2的動(dòng)作,唯一的要求是必須有一個(gè)無(wú)參數(shù)的方法返回String或結(jié)果的對(duì)象,必須是一個(gè)POJO。如果不帶參數(shù)的方法是不指定,則默認(rèn)動(dòng)作是使用execute()方法。
也可以選擇擴(kuò)展ActionSupport類實(shí)現(xiàn)了6個(gè)接口,包括動(dòng)作界面。動(dòng)作界面如下:
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; } }
為了說明這一點(diǎn),操作方法控制視圖,讓我們做出以下更改執(zhí)行方法和擴(kuò)展類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; } }
在這個(gè)例子中,我們有一些在execute方法的邏輯來看待的name屬性。如果屬性等于字符串“SECRET”,我們返回SUCCESS 的結(jié)果,否則我們返回ERROR 的結(jié)果。因?yàn)槲覀円呀?jīng)擴(kuò)展ActionSupport,所以我們可以使用字符串常量的成功和錯(cuò)誤?,F(xiàn)在,讓我們修改我們的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>
創(chuàng)建視圖
讓我們創(chuàng)建以下JSP文件 helloWorld.jsp 的WebContent文件夾在eclipse項(xiàng)目。要做到這一點(diǎn),右鍵單擊WebContent文件夾在項(xiàng)目資源管理器,選擇New >JSP File。該文件將要求返回的結(jié)果是SUCCESS,這是一個(gè)字符串常量“success”的定義在動(dòng)作界面:
<%@ 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>
以下是由框架的動(dòng)作的結(jié)果將被調(diào)用的文件,該文件是等于字符串常量“錯(cuò)誤”的ERROR 。以下是AccessDenied.jsp 的內(nèi)容
<%@ 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文件夾中創(chuàng)建index.jsp。該文件將作為初始動(dòng)作URL,用戶可以直接點(diǎn)擊告訴Struts 2框架調(diào)用HelloWorldAction類的 execute方法,并呈現(xiàn) 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文件,所以讓我們用同一個(gè)web.xml,是之前我們已經(jīng)創(chuàng)建了范例章?,F(xiàn)在,我們已經(jīng)準(zhǔn)備好運(yùn)行使用Struts 2框架的 Hello World應(yīng)用程序。
執(zhí)行應(yīng)用程序
右鍵點(diǎn)擊項(xiàng)目名稱,并單擊 Export > WAR File 創(chuàng)建一個(gè)WAR文件。然后在Tomcat 的webapps目錄下部署這個(gè)WAR。最后,啟動(dòng)Tomcat服務(wù)器和嘗試訪問URL http://localhost:8080/HelloWorldStruts2/index.jsp。這會(huì)給出以下畫面:
讓我們?yōu)椤癝ECRET”,并輸入一個(gè)字,應(yīng)該看到以下頁(yè)面:
現(xiàn)在輸入任何單詞而非“SECRET”,應(yīng)該看到以下頁(yè)面:
建立多個(gè)動(dòng)作:
經(jīng)常會(huì)定義一個(gè)以上的動(dòng)作,以處理不同的請(qǐng)求,并提供不同的用戶的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>
正如看到在上述假設(shè)的例子,動(dòng)作的結(jié)果是重復(fù)的SUCCESS和ERROR。要解決這個(gè)問題,建議創(chuàng)建一個(gè)類包含結(jié)果的結(jié)果。
Struts2 攔截器
攔截器的概念是Servlet過濾器或JDK代理類一樣的。攔截器允許橫切功能分開實(shí)現(xiàn)的動(dòng)作,以及框架。使用攔截器,可以實(shí)現(xiàn)如下:
- 提供預(yù)處理行動(dòng)之前被稱為邏輯。
- 提供后處理邏輯動(dòng)作后被調(diào)用
- 捕獲異常,這樣可以進(jìn)行替代處理。
Struts2框架提供的許多功能都使用攔截實(shí)現(xiàn)的例子包括異常處理,文件上傳,生命周期回調(diào)和驗(yàn)證等事實(shí)上作為Struts2的基礎(chǔ),其功能攔截,這可能有7或8攔截器分配給每個(gè)動(dòng)作。
Struts2框架的攔截器:
Struts 2框架提供了良好的箱攔截列表來預(yù)先設(shè)定的,并準(zhǔn)備使用。下面列出了幾個(gè)重要的攔截:
請(qǐng)看Struts 2文檔的完整細(xì)節(jié)上面提到的攔截。會(huì)告訴如何使用Struts應(yīng)用程序在一個(gè)攔截器。
如何使用攔截器?
讓我們來看看如何使用已有的攔截,我們的“Hello World”程序。我們將使用計(jì)時(shí)器來測(cè)量過了多長(zhǎng)時(shí)間執(zhí)行操作方法,其目的是攔截。同時(shí)使用params攔截器,其目的是發(fā)送請(qǐng)求參數(shù)的動(dòng)作。您可以嘗試不使用這個(gè)攔截您的示例中會(huì)發(fā)現(xiàn),沒有被設(shè)置name屬性,因?yàn)閰?shù)是無(wú)法達(dá)到動(dòng)作。
我們將繼續(xù)HelloWorldAction.java,web.xml 的helloWorld.jsp 和 index.jsp 文件,因?yàn)樗麄円呀?jīng)建立了范例章節(jié),但讓我們?nèi)缦滦薷膕truts.xml文件,添加一個(gè)攔截器
<?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>
右鍵點(diǎn)擊項(xiàng)目名稱,并單擊 Export > WAR File 創(chuàng)建一個(gè)WAR文件。然后部署在Tomcat 的webapps目錄下這個(gè)WAR。最后,啟動(dòng)Tomcat服務(wù)器和嘗試訪問URL http://localhost:8080/HelloWorldStruts2/index.jsp。這會(huì)給你以下畫面:
現(xiàn)在,在給定的文本框中輸入單詞,并單擊“Say Hello按鈕執(zhí)行已定義的動(dòng)作?,F(xiàn)在,如果將檢查生成的日志,會(huì)發(fā)現(xiàn)下面的文字:
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.
這里底行,正在生成因?yàn)檫@告訴動(dòng)作發(fā)生要執(zhí)行的總共為 109ms定時(shí)器的攔截器。
創(chuàng)建自定義的攔截器
在應(yīng)用程序中使用自定義的攔截器是一種優(yōu)雅的方式提供橫切的應(yīng)用功能。創(chuàng)建一個(gè)自定義攔截器是很容易的,需要擴(kuò)展的接口,下面的Interceptor接口:
public interface Interceptor extends Serializable{ void destroy(); void init(); String intercept(ActionInvocation invocation) throws Exception; }
正如其名稱所表明的,init()方法提供了一種方法來初始化攔截器,并destroy() 方法提供了一種工具攔截清理。不同的行動(dòng),攔截被重用跨請(qǐng)求和需要是線程安全的,尤其是intercept() 方法。
ActionInvocation對(duì)象可以訪問運(yùn)行時(shí)環(huán)境。它允許訪問的動(dòng)作本身和方法調(diào)用的動(dòng)作,并確定動(dòng)作是否已被調(diào)用。
如果不需要初始化或清除代碼,可以擴(kuò)展AbstractInterceptor類。這提供了一個(gè)默認(rèn)的無(wú)操作實(shí)現(xiàn)的init()和 destroy()方法。
創(chuàng)建攔截器類:
讓我們創(chuàng)建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; } }
就像看到的,實(shí)際行動(dòng)將使用攔截器執(zhí)行invocation.invoke()調(diào)用。所以,可以做一些前處理和一些處理后,根據(jù)需要。
該框架本身啟動(dòng)的過程中,在第一次調(diào)用ActionInvocation對(duì)象的invoke()。每次 invoke()被調(diào)用,ActionInvocation的咨詢的狀態(tài)和執(zhí)行為準(zhǔn)攔截接下來。通過請(qǐng)求流以下數(shù)據(jù)圖顯示了相同的概念:
創(chuàng)建動(dòng)作類:
讓我們創(chuàng)建一個(gè)Java文件HelloWorldAction.java的Java下Java Resources > src下面給出的內(nèi)容包名為 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; } }
在前面的例子中,我們已經(jīng)看到,這是一個(gè)相同的類。我們有標(biāo)準(zhǔn)的“名稱”屬性的getter和setter方法,并返回字符串“success”的執(zhí)行方法。
創(chuàng)建視圖
讓我們創(chuàng)建以下JSP文件helloWorld.jsp,在eclipse項(xiàng)目在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>
創(chuàng)建頁(yè)面:
我們還需要在WebContent文件夾中創(chuàng)建 index.jsp。該文件將作為初始動(dòng)作URL,用戶可以在其中點(diǎn)擊告訴Struts 2框架調(diào)用 HelloWorldAction類定義的方法呈現(xiàn) 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 動(dòng)作定義在上面的視圖文件將被映射到HelloWorldAction類和其執(zhí)行方法使用struts.xml文件。
配置文件
現(xiàn)在,我們需要注冊(cè)我們的攔截器,然后調(diào)用它默認(rèn)的攔截器在前面的例子中調(diào)用。要注冊(cè)一個(gè)新定義的攔截,直接放在的<interceptors>...</interceptors>標(biāo)簽下<package>的標(biāo)簽插件struts.xml文件。您可以跳過這一步為默認(rèn)的攔截器,就像我們?cè)谖覀兦懊娴睦?。但在這里,讓我們注冊(cè)和使用它,如下所示:
<?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>
應(yīng)該指出的是,可以注冊(cè)多個(gè)攔截器<package>標(biāo)簽內(nèi),同一時(shí)間,可以調(diào)用多個(gè)攔截里面的<action>標(biāo)簽??梢哉{(diào)用相同的攔截器與不同的動(dòng)作。
web.xml文件需要在 WEB-INF文件夾下創(chuàng)建 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>
右鍵點(diǎn)擊項(xiàng)目名稱,并單擊 Export > WAR File 文件創(chuàng)建一個(gè)WAR文件。然后部署在Tomcat 的webapps目錄下這個(gè)WAR。最后,啟動(dòng)Tomcat 服務(wù)器和嘗試訪問URL http://localhost:8080/HelloWorldStruts2/index.jsp。這會(huì)給你以下畫面:
現(xiàn)在,在給定的文本框中輸入任何單詞,并單擊“Say Hello“ 按鈕執(zhí)行已定義的動(dòng)作?,F(xiàn)在,如果檢查生成的日志,會(huì)發(fā)現(xiàn)下面的文本下方:
Pre-Processing Inside action.... Post-Processing
堆疊多個(gè)攔截器:
可以想像,配置多個(gè)攔截器每個(gè)動(dòng)作很快就會(huì)變得非常難以控制。出于這個(gè)原因,攔截器與攔截器棧管理。下面是一個(gè)例子,直接從在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>
上面的棧被調(diào)用basicStack,可用于在配置中,如下所示。此配置節(jié)點(diǎn)放置在<package.../>節(jié)點(diǎn)下。每個(gè)<interceptor-ref.../>標(biāo)記引用一個(gè)攔截器或攔截器棧已配置在當(dāng)前的攔截器棧。因此,這是非常重要的,以確保該名稱是唯一的所有攔截器和攔截器棧配置配置初始的攔截器和攔截器棧時(shí)。
我們已經(jīng)看到了如何應(yīng)用攔截的動(dòng)作,將攔截器棧是沒有什么不同。事實(shí)上,我們完全使用相同的標(biāo)簽:
<action name="hello" class="com.yiibai.struts2.MyAction"> <interceptor-ref name="basicStack"/> <result>view.jsp</result> </action
上述注冊(cè)的“basicStack”所有6個(gè)攔截器完成注冊(cè)的棧 Hello 動(dòng)作。應(yīng)該指出的是,攔截器執(zhí)行的順序在配置中。例如,在上述情況下,異常將被執(zhí)行,servlet 配置等。
- Java的Struts框架中配置國(guó)際化的資源存儲(chǔ)的要點(diǎn)解析
- 深入解析Java的Struts框架中的控制器DispatchAction
- 詳解Java的Struts框架以及相關(guān)的MVC設(shè)計(jì)理念
- Java的Struts框架中登陸功能的實(shí)現(xiàn)和表單處理器的使用
- Java的Struts框架中append標(biāo)簽與generator標(biāo)簽的使用
- 簡(jiǎn)單說明Java的Struts框架中merge標(biāo)簽的使用方法
- 總結(jié)Java的Struts框架的異常處理方法
- 詳解Java的Struts框架中注釋的用法
- Java下Struts框架中的ActionForm類詳解
相關(guān)文章
Java數(shù)據(jù)結(jié)構(gòu)之線段樹的原理與實(shí)現(xiàn)
線段樹是一種二叉搜索樹,是用來維護(hù)區(qū)間信息的數(shù)據(jù)結(jié)構(gòu)。本文將利用示例詳細(xì)講講Java數(shù)據(jù)結(jié)構(gòu)中線段樹的原理與實(shí)現(xiàn),需要的可以參考一下2022-06-06Spring注解驅(qū)動(dòng)之BeanDefinitionRegistryPostProcessor原理解析
這篇文章主要介紹了Spring注解驅(qū)動(dòng)之BeanDefinitionRegistryPostProcessor原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09Gradle jvm插件系列教程之Java?Library插件權(quán)威詳解
這篇文章主要介紹了Java?Library插件權(quán)威詳解,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01關(guān)于Javaweb的轉(zhuǎn)發(fā)和重定向詳解
這篇文章主要介紹了關(guān)于Javaweb的轉(zhuǎn)發(fā)和重定向詳解,請(qǐng)求的轉(zhuǎn)發(fā),是指服務(wù)器收到請(qǐng)求后,從一個(gè)服務(wù)器端資源跳轉(zhuǎn)到同一個(gè)服務(wù)器端另外一個(gè)資源的操作,需要的朋友可以參考下2023-05-05SpringSecurity詳解整合JWT實(shí)現(xiàn)全過程
JWT作為一個(gè)開放的標(biāo)準(zhǔn)(?RFC?7519?),定義了一種簡(jiǎn)潔的,自包含的方法用于通信雙方之間以Json對(duì)象的形式安全的傳遞信息。接下來通過本文給大家介紹springSecurity+jwt實(shí)現(xiàn)互踢功能,需要的朋友可以參考下2022-07-07解決java.lang.Error: Unresolved compilation pro
這篇文章主要介紹了解決java.lang.Error: Unresolved compilation problems:問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03