轉自:http://blog.sina.com.cn/s/blog_722e24e70100npay.html
- Struts的5個核心轉自元件
1. Actions: model
2. Interceptors: controller
3. Value stack / OGNL: provide common thread, linking and enabling integration between the other components
4. Resut types: view
5. Results / view technologies: view
- Struts2 configuration file
1. struts.properties
這個檔案用來改變struts的預設行為,通常不用修改。所有這個檔案中的內容可以用web.xml中的’’init-param’或者 struts.xml中的”constant”來覆蓋。預設的檔案位於struts核心jar包的org.apache.struts2包下,default.properties.
為了開發方便,通常修改一下幾個屬性(在src root下建立struts.properties即可):
ü struts.i18n.reload = true 自動reload國際化檔案
ü struts.devMode = true 開發模式,更易於理解的除錯資訊
ü struts.configuration.xml.reload reload一個xml配置檔案而不是整個應用
ü struts.url.http.port = 8080 埠
ü struts.i18n.encoding= GBK 用於中文環境
2. struts.xml
1) Include: 用於模組化配置檔案,可將struts.xml分開並由此tag引入。引入是順序相關的。有些配置檔案是自動載入的:struts- default.xml、truts-plugin.xml。前者是struts核心的配置檔案,主要定義了預設的許多interceptors以及返回 型別,後者提供了特定plug-in的配置。
2) Package:用於分組。同一組通常共享一些屬性諸如interceptor stack或URL namespace。通常用於分開特定的功能模組。
Name:標識而已
Extends:引入別的包,類似於java的繼承。通常extends struts-default.xml
Namespace:URL到package的對映,例如兩個同樣的action不同的namespace就會有不同的configuration:如/myWebApp/package1/my.action”“/myWebApp/package2/my.action”
Abstract:若為true,則action通過package訪問不到。
另外,package下可以有 tag。
Actions
首先,struts中的action是POJO,即不必要(但可以)繼承任何父類或者實現任何介面。其次action有一個方法execute(),返回string(結果)。
一個例子:
view.jsp
error.jsp
其中name提供了執行這個action的URL資訊,/my.action。字尾.action定義在struts.properties中,可以改變。
1. 有4種決定action結果的方式。(待完善)
2. result types:下面是struets種定義的result type,還可以自定義,其中預設為dispacther(forward),redirect可以用來返回到登入頁面。
Struts遵循javabean的範例,用setter和getter。如:呼叫home.action的 URL“/home.action?framework=struts&version=2”需要action提供setFramework() 方法。struts2提供了對原子資料型別及簡單物件的的自動轉換。
4. 訪問business service
下面是struets種定義的result type,還可以自定義,其中預設為dispacther(forward),redirect可以用來返回到登入頁面
5. 通過action訪問表單資料
1) 通過實現“aware”介面
2) Built-in tag lib. 通過value stack來訪問(action提供相應名稱的getter)。
Interceptors 攔截器
攔截器與servlet中的filter是很類似的。(過濾器請求先進入filter,進入過濾器鏈,而後進入真正的servlet,而後再回到filter)
1. Interceptor實現機制
首先,一個目標物件(被攔截的物件,實際中為action)tagart object
public interface TargetInterface {
public void doSomething();
}
public class Target implements TargetInterface
{
public void doSomething()
{
System.out.println("do something");
}
}
其次,攔截器
public class Interceptor{
public void before(){
System.out.println("before");
}
public void after(){
System.out.println("after");
}
}
然後,實現InvocationHandler(實際中這個類應該是struts容器實現的)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyHandler implements InvocationHandler {
private Object object;
private Interceptor interceptor = new Interceptor();
public void setObject(Object object){
this.object = object;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
Object result = null;
interceptor.before();
result = method.invoke(object, args);
interceptor.after();
return result;
}
}
最後,需要一個代理類(實際中也是由struts利用java的反射機制動態生成的)
import java.lang.reflect.Proxy;
public class MyProxy{
public Object getProxy(Object object){
MyHandler myHandler = new MyHandler();
myHandler.setObject(object);
return Proxy.newProxyInstance(Target.class.getClassLoader(), object
.getClass().getInterfaces(), myHandler);
}
}
Client來展示如何呼叫:
public class Client {
public static void main(String[] args) {
TargetInterface target = new Target();
MyProxy myProxy = new MyProxy();
TargetInterface proxy = (TargetInterface)myProxy.getProxy(target);
proxy.doSomething();
}
}
其中,Target和Interceptor是我們來實現的,然而他們彼此並沒有耦合。在執行當中,struts會通過配置檔案自動生成handler和 proxy將他們聯絡在一起,這種動態耦合的方式增加了系統的靈活性。在struts和spring框架中中這種方式被大量採用。
2. interceptor配置
1)在配置檔案struts.xml中配置interceptor
…
class="interceptor.ActionAutowiringInterceptor"/>
2) 在action中引用
view.jsp
當有多個interceptor時順序排在前面的優先。
可以定義為預設interceptor,自動應用到每個action中
3) 定義interceptor stack來同時應用多個interceptor,stack可以巢狀定義。例如在struts-default.xml中定義了
可以refer到一個interceptor或者interceptor stack,在struts看來是interceptor和stack一樣的。如:
view.jsp
3. 開發interceptor
兩種方法:
1) 實現介面Interceptor
2)繼承AbstractInterceptor(這個類其實是實現了Interceptor介面,而把init和destroy空實現,因為這兩個方法不常用,而留下intercept方法給使用者實現)
例如:
public String intercept(ActionInvocation invocation) throws Exception{
System.out.println("intercept");
String result = invocation.invoke();
System.out.println("finish");
return result;
}
Value Stack / OGNL(Object Graph Navigational Language)
OGNL(Object Graph Navigational Language), 提供了統一的方法來訪問value stack。 1. value stack則包含了下面幾種物件:
- 臨時物件(temporary objects):執行過程臨時建立的物件,例如在對一個集合類物件執行迴圈的時候當前的迭代值
- 模型物件(model object):模型物件在action物件放入前進入VS
- Action物件(action object)action本身
- 命名物件(named objects)包括 #application,#session, #request, #attr 和 #parameters等指向相應的servlet scope。
2. 訪問VS的途徑:
- Tag: 包括JSP、Velocity、Freemarker等提供的。HTML tag是獲取vs data經常的途徑
- OGNL
3. 使用vs時候不用care它的作用域,只要vs中存在相應名稱的property,就可以得到value,struts會自動loop整個stack
但是當我們需要訪問一個common name的物件時(比如id),就會得到第一個(也許並不是我們想要的),這時就會用到OGNL。
http://www.opensymphony.com/ognl/
Return Types
其實return給client的不單單可以是JSP頁面。Struts定義了很多型別的return type。
1. 配置
例如:返回jsp頁面的例子(forward)
view.jsp
2. 定義一個return type
在下定義,類似於interceptor,其中clas代表實現類,而default則表示預設的return type
class="….dispatcher.ServletDispatcherResult"/>
class="….dispatcher.ServletRedirectResult"/>
…
3. 實現return type
除了struts預設提供的,還可以自定義return type,實現下面的介面即可:
public interface Result extends Serializable {
public void execute(ActionInvocation invocation)throws Exception;
}
ActionInvocation提供了對執行時環境的訪問,可以使return type訪問到action執行過後的資訊,以及action執行時的環境資訊。其中包含有HttpServletRequest物件,可以難倒當前request的輸出流。