Struts2學習之1(Struts2的工作流程,動作類的編寫,struts.xml配置檔案的編寫)
Struts2的開始
Struts2的作用
現在專案一般都是按照三層架構來開發的,表現層,業務邏輯層,資料訪問層,Struts2就是用來代替servlet處理表現層的一種框架,用來處理頁面的請求跳轉與資料顯示等,Struts2裡面還是用servlet來實現的,只不過被高度封裝了。
搭建Struts2開發環境
下載jar包
拷貝jar包到專案中去
開啟Struts2發行包\apps\struts2-blank\WEB-INF\lib,把其中jar都拷貝過來即可。
編寫配置檔案
在構建路徑的頂端,建立一個配置檔案struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
</struts>
宣告部分可以拷貝struts-core-xxx.jar中的struts-default.xml裡的頭部宣告。
配置控制對映
在專案的web.xml中配置如下資訊
<!-- 配置Struts2框架的核心控制器 -->
<filter >
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern >
</filter-mapping>
開始一個小例子
頁面編寫
<body>
<a href="${pageContext.request.contextPath}/uuu/helloWorld.action">點選</a>
</body>
配置檔案編寫
<struts>
<!-- name為包名,唯一的; namespace為名稱空間,先找到namespace,找到了就在當前namespace下找action,找不到action則在預設的namespace下找action,extends是繼承某個包,預設寫struts-default,該包可以在struts-default.xml中找到 -->
<package name="p1" extends="struts-default" namespace="/uuu">
<!-- name為請求連結名(動作名稱),class為請求的類全名,預設為com.opensymphony.xwork2.ActionSupport
method為請求類裡的處理方法,預設為execute() -->
<action name="helloWorld" class="com.jyh.action.HelloWorldAction" method="sayHello">
<!-- result為返回的頁面 -->
<result name="success">/success.jsp</result>
<result name="error">/error.jsp</result>
</action>
</package>
</struts>
動作類編寫
package com.jyh.action;
public class HelloWorldAction {
public String sayHello(){
return "success";
}
}
結果檢視編寫
建立success.jsp和error.jsp
案例執行過程簡析
頁面點擊發送請求,由web.xml配置檔案中配置的struts攔截器攔截,讀取struts中的配置,先找到namespace,然後在對應的namespace下找到action,然後到action中class指向的類中找到method指向的方法,返回的字串與result中的name屬性匹配,然後跳轉到結果頁面。頁面中的連結就是:當前專案路徑/namespace/action.name。
動作類
動作類的三種編寫方式
方式一
如上圖所示,直接編寫一個普通的類
方式二
實現com.opensymphony.xwork2.Action介面
package com.jyh.action;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class Demo1 extends ActionSupport {
public String execute() throws Exception {
return SUCCESS;
}
}
Action介面中的常量:
String SUCCESS:success。一切正常。
String NONE:none。動作方法執行後,不轉向任何的結果檢視。或者在動作方法中返回null。
String ERROR:error。動作方法執行時遇到異常,轉向錯誤提示頁面。
String INPUT:input。驗證、轉換失敗,轉向輸入頁面。
String LOGIN:login。檢測使用者是否登入,沒有登入轉向此檢視。
方式三
繼承com.opensymphony.xwork2.ActionSupport(推薦)
意義:提供了一些基本的功能。比如驗證和國際化訊息提示等。
動作類中動作方法的編寫
public String xxx(){};
動作類的萬用字元對映
<!-- name中的*號代表定義一個萬用字元,頁面的連結與name屬性匹配代表給萬用字元*賦值,如頁面中連結為addCustomerUI
則表示第一個*為add,第二個*為UI,後面的{1}代表引用第一個統配符號,以*在name屬性出現的順序為序號來引用,
所以可以看成method="add",result轉向頁面為/customer/UICustomer.jsp -->
<action name="*Customer*" class="com.jyh.action.CustomerAction" method="{1}">
<result name="success">/customer/{2}Customer.jsp</result>
</action>
動態方法呼叫:DMI(Dynamic Method Invocation)
在訪問時指定執行的動作方法:
http://localhost:8080/XXX/demo4!m1 執行demo4動作對應動作類的m1動作方法
預設情況下:會報錯,說找不到demo4!m1這個動作方法。因為struts2框架預設是禁止動態方法呼叫的。
<constant name="struts.enable.DynamicMethodInvocation" value="true">
注意:不建議使用。容易暴露動作類中的動作方法,害怕非法執行。
動作類獲取ServletAPI
方式一(推薦)
package com.jyh.action;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class ServletAction extends ActionSupport {
@Override
public String execute() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
ServletContext context = ServletActionContext.getServletContext();
System.out.println(request);
System.out.println(response);
System.out.println(context);
return null;
}
}
方式二
package com.jyh.action;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.util.ServletContextAware;
public class ServletAction2 implements ServletRequestAware,ServletResponseAware,ServletContextAware {
/**
* 攔截器注入的這些東西(servletConfig攔截器)
*/
private HttpServletRequest request;
private HttpServletResponse response;
private ServletContext context;
public String execute() throws Exception {
System.out.println(request);
System.out.println(response);
System.out.println(context);
return null;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public void setServletContext(ServletContext context) {
this.context = context;
}
}
Struts2配置檔案struts.xml
Struts2的其它一些配置檔案和寫法
自帶的一些配置檔案
- default.properties:struts2-core**.jar org.apache.struts包中(只讀)
- struts-default.xml:struts2-core**.jar中(只讀)
- struts-plugin.xml:在外掛的jar包中(只讀)
- struts.xml:在應用的構建路徑頂端。自己定義的Struts配置檔案(推薦)
- struts.properties:在應用的構建路徑頂端。自己編寫(不推薦)
- web.xml:配置過濾器時,指定引數。自己編寫(不推薦)
特別注意:順序是固定的。後面的配置會覆蓋前面的同名配置資訊。
一些常用的預設引數的修改與設定
包含其他配置檔案
<include file="user.xml"></include>
<!-- 修改連結預設字尾,多個字尾可以用逗號隔開 -->
<constant name="struts.action.extension" value="do"></constant>
<!-- 設定瀏覽器是否快取靜態內容,預設值為true -->
<constant name="struts.serve.static.browserCache" value="false"></constant>
<!-- 當struts的配置檔案修改後系統是否自動重新載入該檔案,預設值為false,推薦開啟 -->
<constant name="struts.configuration.xml.reload" value="true"></constant>
<!-- 開發模式,會非常詳細的打印出一些錯誤資訊,開啟它則預設開啟了i18n.reload、configuration.xml.reload。 -->
<constant name="struts.devMode" value="true"></constant>
<!-- 檢視主題(simple,xhtml,css_xhtml),預設為xhtml,也就是struts2自帶的檢視主題,simple為不普通的標籤不帶任何主題 -->
<constant name="struts.ui.theme" value="simple"></constant>
<!-- 與spring整合時,指定由spring負責action物件的建立 -->
<constant name="struts.objectFactory" value="spring"></constant>
<!-- 該屬性設定struts是否支援動態方法呼叫,預設為false-->
<constant name="struts.enable.DynamicMethodInvocation" value="false"></constant>
<!-- 上傳檔案大小限制 -->
<constant name="struts.multipart.maxSize" value="100000000"></constant>
package元素
意義:分模組開發。
屬性:
- name:必須的。配置檔案中要唯一。就是一個名字。
- extends:指定父包。會把父包中的配置內容繼承下來。一般需要直接或間接的繼承一個叫做“struts-default”的包(在struts-default.xml配置檔案中)。如果不繼承該包,那麼Struts2中的核心功能將無法使用。
- abstract:是否是抽象包。沒有任何action子元素的package可以宣告為抽象包。
- namespace:指定名稱空間。一般以”/”開頭。該包中的動作訪問路徑:namesapce+動作名稱。如果namespace=””,這是預設名稱空間,和不寫該屬性是一樣的。
action元素
作用:定義一個動作。
屬性:
- name:必須的。動作名稱。使用者用於發起請求。在包中要唯一。
- class:指定動作類的全名。框架會通過反射機制例項化。預設是:com.opensymphony.xwork2.ActionSupport。
- method:指定動作類中的動作方法。框架會執行該方法。預設是execute()。
預設類在struts-default.xml中聲明瞭,也可以用
<default-class-ref class="完整類名"></default-class-ref>
覆蓋
結果檢視result元素
- name:邏輯檢視名稱。它對應的是動作方法的返回值。預設值:success。
type:結果型別,到達目標的形式。預設值:dispatcher-轉發。
全域性檢視:
<global-results></global-results>
,直接寫在包下- 區域性檢視:
<results></global>
,寫在action下
在什麼下範圍就多大,先找action下的區域性檢視(範圍精確),再找報下的全域性檢視
預設擁有的結果型別(result的type元素)
struts-default.xml中定義的結果檢視
<result-types>
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
<result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
<result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
<result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
<result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
<result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
<result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
</result-types>
- freemarker:用於轉發到另外一個freemarker模板。(頁面靜態化)
- velocity:用於轉發到另外一個velocity模板。
- httpheader:用於輸出http協議的訊息頭。
- xslt:XML有關的樣式
- redirect:用於重定向到另外一個JSP頁面。
- redirectAction:用於重定向到另外一個動作。
- stream:用於檔案下載(日後再講。檔案上傳和下載)
- plainText:以純文字的形式展現頁面。輸出原始碼。
- chain:使用者轉發到另外一個動作。
- dispatcher:用於轉發到另外一個JSP頁面。
<!-- 同一個包下一個動作轉發到另一個動作 -->
<package name="d1" extends="struts-default" namespace="/n1">
<action name="demo1" class="com.jyh.action.Demo1" method="execute">
<result name="success" type="chain">demo2</result>
</action>
<action name="demo2" class="com.jyh.action.Demo1" method="execute">
<!-- <result name="success" type="dispatcher">/demo1.jsp</result> -->
<!-- 同上,dispatcher表示轉發到頁面 -->
<result name="success" type="dispatcher">
<param name="location">/demo1.jsp</param>
</result>
</action>
</package>
<!-- 轉發到另一個包中的動作 -->
<package name="d2" extends="struts-default" namespace="/n2">
<action name="demo3" class="com.jyh.action.Demo1" method="execute">
<result name="success" type="chain"><!-- 配置type="chain"意思是從這個動作跳到另一個動作 -->
<param name="namespace">/n1</param><!-- 配置轉發目標動作所在的名稱空間 -->
<param name="actionName">demo2</param><!-- 配置轉發目標動作的名稱 -->
</result>
</action>
</package>
自定義結果型別(result的type元素)
1.編寫一個類,直接或間接實現com.opensymphony.xwork2.Result介面。一般繼承org.apache.struts2.dispatcher.StrutsResultSupport類
package com.jyh.action;
/**
* 自定義結果型別,生成驗證碼
*/
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.StrutsResultSupport;
import cn.dsna.util.images.ValidateCode;
import com.opensymphony.xwork2.ActionInvocation;
@SuppressWarnings("serial")
public class CaptchaResult extends StrutsResultSupport {
private int width = 200;//長度
private int height = 80;//寬度
private int codeCount = 4;//驗證碼個數
private int lineCount = 100;//干擾線條數
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public void setCodeCount(int codeCount) {
this.codeCount = codeCount;
}
public void setLineCount(int lineCount) {
this.lineCount = lineCount;
}
protected void doExecute(String finalLocation, ActionInvocation invocation)
throws Exception {
ValidateCode vCode = new ValidateCode(width, height, codeCount, lineCount);
BufferedImage image = vCode.getBuffImg();
HttpServletResponse response = ServletActionContext.getResponse();
ImageIO.write(image, "jpeg", response.getOutputStream());
}
}
2.宣告定義結果型別
<!-- 自定義結果型別 -->
<package name="d3" extends="struts-default">
<!-- 宣告定義結果型別 -->
<result-types>
<!-- name為結果型別名稱,class為具體實現的類 -->
<result-type name="captcha" class="com.jyh.action.CaptchaResult"/>
</result-types>
</package>
3.使用自定義的結果型別
<action name="captcha">
<!-- 使用定義的結果型別 -->
<result name="success" type="captcha">
<!-- 設定結果型別對應的實現類中的屬性 -->
<param name="width">200</param>
<param name="height">80</param>
<param name="codeCount">4</param>
<param name="lineCount">100</param>
</result>
</action>