前言 上篇Struts博文已經講解了Struts的開發步驟以及執行流程了.....對Struts的配置文件有了瞭解.....本博文繼續講解 Struts在配置的時候一些值得要學習的細節 ... 通配符 為什麼要學習通配符 在講解通配符之前,我們來看一下需求..... 現在我的 Action中有兩個方 ...
前言
上篇Struts博文已經講解了Struts的開發步驟以及執行流程了.....對Struts的配置文件有了瞭解.....本博文繼續講解Struts在配置的時候一些值得要學習的細節...
通配符
為什麼要學習通配符
在講解通配符之前,我們來看一下需求.....
現在我的Action中有兩個方法,處理登陸和處理註冊:
public class PrivilegeAction extends ActionSupport {
public String login() {
System.out.println("我是登陸");
return "success";
}
public String register() {
System.out.println("我是註冊");
return "success";
}
}
因此,我們就需要在struts.xml文件中配置兩個action節點
<action name="login" class="privilegeaction.PrivilegeAction" method="login">
<result name="success">/index.jsp</result>
</action>
<action name="register" class="privilegeaction.PrivilegeAction" method="register">
<result name="success">/index.jsp</result>
</action>
現在我們發現:它們僅僅只有訪問路徑和方法的名稱是不一樣的....但是這卻要多配置一個action節點,會造成浪費!
於是乎通配符就應運而生了...
使用通配符改造
沒有通配符之前,我們是需要配置兩個action的...有了通配符,我們是這樣做的:
<package name="privilige" extends="struts-default">
<action name="privilege_*" class="privilegeaction.PrivilegeAction" method="{1}">
<result name="success">/index.jsp</result>
</action>
</package>
解釋一下:
name=privilege_*
,我們用了_作為分隔符。*就是我們的通配符{1}
,就是代表著第一個通配符
我們來看一下效果:
同理可得,當我們在地址欄訪問login的時候,就會執行login的方法
Struts中路徑的匹配原則
有的時候,我們可能會在package節點中指定namespace名稱空間,我們在訪問對應的資源名稱的時候,就需要在前面加入相對應名稱空間的值...
比如:
名稱空間的值為“/user”
<package name="privilige" extends="struts-default" namespace="/user">
<action name="privilege_*" class="privilegeaction.PrivilegeAction" method="{1}">
<result name="success">/index.jsp</result>
</action>
</package>
那麼在訪問資源的時候,就需要在項目名稱後邊加上名稱空間的值:
現在就有一個很奇怪妙的事情發生了:在名稱空間和資源路徑的中間可添加任意的路徑
但是呢,不能在名稱空間之前加入不存在的路徑:
其實這就涉及到了Struts中路徑的匹配原則,我就拿隨便拿個路徑來舉例子http://localhost:8080/user/a/a/privilege_login
:
- 首先,Struts會把請求的資源路徑拿到,也就是
privilege_login
。 - 然後在看看有沒有
/user/a/a
這個名稱空間;如果有,就返回結果 - 如果沒有,就看看有沒有
/user/a
這個名稱空間;如果有,就返回結果 - 如果沒有,再看看有沒有
/user
這個名稱空間;如果有,就返回結果 - 直到最後,如果都沒有找到,就報錯!
看完這個例子,我們就可以知道為啥在名稱空間和資源路徑的中間可添加任意的路徑,而不能在名稱空間之前加入不存在的路徑....這就是Struts的路徑匹配原則..
Struts常量
Struts2預設的訪問尾碼是.action......
修改預設訪問路徑
有的時候,可能根據項目的需要...我想尾碼名預設並不是.action,那我該怎麼辦呢??
我們在jar包上找到它的配置文件...
我們發現它的預設值是action,,
值得註意的是:兩個逗號並不是多餘的
我們不可能是直接修改jar包中的配置文件的,在struts.xml文件中提供了constant節點供我們修改struts的常量...
前面已經說了,兩個逗號並不是多餘的。那麼直接在配置文件中配置action時,會怎麼樣:
<constant name="struts.action.extension" value="action"/>
也就是說,“,”號能夠匹配空格鍵
舉例子說明:
- 如果配置尾碼為
action
。那麼尾碼一定要寫action - 如果配置尾碼為
action,do,
。那麼尾碼可以是action,可以是do,也可以不寫 - 如果配置尾碼為
action,,
。那麼尾碼可以是action,可以不寫
Struts常用的常量
<struts>
<!-- 0. 請求數據編碼 -->
<constant name="struts.i18n.encoding" value="UTF-8"/>
<!-- 1. 修改Struts預設的訪問尾碼 -->
<constant name="struts.action.extension" value="action,do,"></constant>
<!-- 2. 修改xml自動重新載入 -->
<constant name="struts.configuration.xml.reload" value="true"/>
<!-- 3. 開啟動態方法調用 (預設不開啟)-->
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<!-- 4. 修改上傳文件的最大大小為30M -->
<constant name="struts.multipart.maxSize" value="31457280"/>
</struts>
只有動態方法調用是我們沒有接觸過的。
那動態方法調用是怎麼回事呢???這是樣的:在action節點不配置method屬性,在地址欄使用資源名稱!方法名
的方式去調用業務方法
跳轉全局視圖
為什麼需要跳轉全局視圖?
首先,我們還是來看一個需求:現在我有兩個Action,PrivilegeAction和CategoryAction
- PrivilegeAction
```java
public class PrivilegeAction extends ActionSupport {
public String login() {
System.out.println("我是登陸");
return "success";
}
public String register() {
System.out.println("我是註冊");
return "success";
}
}
```
- CategoryAction
public class CategoryAction extends ActionSupport {
public String add() {
System.out.println("我是添加");
return "success";
}
public String find() {
System.out.println("我是查找");
return "success";
}
}
- 在struts.xml文件中配置
<action name="privilege_*" class="privilegeaction.PrivilegeAction" method="{1}">
<result name="success">/index.jsp</result>
</action>
<action name="category_*" class="privilegeaction.CategoryAction" method="{1}">
<result name="success">/index.jsp</result>
</action>
我們發現一個問題,只要是方法返回值是success,那麼就跳轉到首頁....如果有大量Action方法返回的都是success,那麼就要寫很多很多個result節點了..
使用跳轉全局視圖
- 代碼就可以變成是這樣子了,註意:
global-results
節點需要在action節點的上面
<package name="privilige" extends="struts-default" >
<global-results>
<result name="success">/index.jsp</result>
</global-results>
<action name="privilege_*" class="privilegeaction.PrivilegeAction" method="{1}">
</action>
<action name="category_*" class="privilegeaction.CategoryAction" method="{1}">
</action>
</package>
- 效果:
Action節點中的預設配置
一份相對完整的action節點是這樣子的:
<action name="privilege_*" class="privilegeaction.PrivilegeAction" method="{1}">
</action>
method
如果我們不寫method的話,預設執行的是execute()方法,execute()方法預設返回值是SUCCESS
public class BBAtion extends ActionSupport {
@Override
public String execute() throws Exception {
System.out.println("我是execute()");
return SUCCESS;
}
}
class
如果不寫class,class預設執行的action在struts-default有配置<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
什麼時候會不寫class?就是需要跳轉到WEB-INF目錄下的資源的時候.....這就類似與Servlet需要跳轉到WEB-INF下的資源。【Tomcat不允許直接訪問WEB-INF資源】
<!-- 什麼情況不配置class? 即處理的aciton -->
<!-- 答案: 當只是需要跳轉到WEB-INF下資源的時候。 -->
<action name="test2">
<result name="success" >/WEB-INF/index.jsp</result>
</action>
如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關註微信公眾號:Java3y