Struts
框架本身大致可以分為
個部分
核心控制器FilterDispatcher
業務控制器Action和用戶實現的企業業務邏輯組件
核心控制器FilterDispatcher
核心控制器 FilterDispatcher是Struts
框架的基礎
包含了框架內部的控制流程和處理機制
業務控制器Action和業務邏輯組件是需要用戶來自己實現的
用戶在開發Action和業務邏輯組件的同時
還需要編寫相關的配置文件
供核心控制器FilterDispatcher來使用
Struts
的工作流程相對於Struts
要簡單
與WebWork框架基本相同
所以說Struts
是WebWork的升級版本
Struts
框架按照模塊來劃分
可以分為Servlet Filters
Struts核心模塊
攔截器和用戶實現部分
Struts
框架結構圖如圖
所示
圖
Struts
框架結構圖
一個請求在Struts
框架中的處理大概分為以下幾個步驟
客戶端提交一個(HttpServletRequest)請求
如上文在浏覽器中輸入
就是提交一個(HttpServletRequest)請求
請求被提交到一系列(主要是
層)的過濾器(Filter)
如(ActionContextCleanUp
其他過濾器(SiteMesh等)
FilterDispatcher)
注意
這裡是有順序的
先ActionContext CleanUp
再其他過濾器(Othter Filters
SiteMesh等)
最後到FilterDispatcher
FilterDispatcher是控制器的核心
就是MVC的Struts
實現中控制層(Controller)的核心
FilterDispatcher詢問ActionMapper是否需要調用某個Action來處理這個(HttpServlet Request)請求
如果ActionMapper決定需要調用某個Action
FilterDispatcher則把請求的處理交給ActionProxy
ActionProxy通過Configuration Manager(struts
xml)詢問框架的配置文件
找到需要調用的Action類
例如
用戶注冊示例將找到UserReg類
ActionProxy創建一個ActionInvocation實例
同時ActionInvocation通過代理模式調用Action
但在調用之前
ActionInvocation會根據配置加載Action相關的所有Interceptor(攔截器)
一旦Action執行完畢
ActionInvocation負責根據struts
xml中的配置找到對應的返回結果result
Struts
的核心控制器是FilterDispatcher
有
個重要的方法
destroy()
doFilter()和Init()
可以在Struts
的下載文件夾中找到源代碼
如代碼
所示
代碼
核心控制器FilterDispatcher
public class FilterDispatcher implements StrutsStatics
Filter {
/**
* 定義一個Log實例
*/
private static final Log LOG = LogFactory
getLog(FilterDispatcher
class)
… …
/**
* 存放屬性文件中的
STRUTS_I
N_ENCODING值
*/
private static String encoding;
/**
* 定義ActionMapper實例
*/
private static ActionMapper actionMapper;
/**
* 定義FilterConfig實例
*/
private FilterConfig filterConfig;
protected Dispatcher dispatcher;
/**
* 創建一個默認的dispatcher
初始化filter
* 設置默認的packages *
*/
public void init(FilterConfig filterConfig) throws ServletException {
this
filterConfig = filterConfig;
dispatcher = createDispatcher(filterConfig)
dispatcher
init()
String param = filterConfig
getInitParameter(
packages
)
String packages =
org
apache
struts
static template org
apache
struts
interceptor
debugging
;
if (param != null) {
packages = param +
+ packages;
}
this
pathPrefixes = parse(packages)
}
//銷毀filter方法
public void destroy() {
if (dispatcher == null) {
LOG
warn(
something is seriously wrong
Dispatcher is not initialized (null)
)
} else {
dispatcher
cleanup()
}
}
/**
* 處理一個Action或者資源請求
*
* filter嘗試將請求同action mapping相匹配
* 如果找到
將執行dispatcher的serviceAction方法
* 如果Action處理失敗
doFilter將建立一個異常
*
* 如果請求靜態資源
* 資源將被直接復制給 response
*
* 如果找不到匹配Action 或者靜態資源
則直接跳出
public void doFilter(ServletRequest req
ServletResponse res
FilterChain chain) throws IOException
ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
ServletContext servletContext = getServletContext()
String timerKey =
FilterDispatcher_doFilter:
;
try {
UtilTimerStack
push(timerKey)
request = prepareDispatcherAndWrapRequest(request
response)
ActionMapping mapping;
try {
mapping=actionMapper
getMapping(request
dispatcher
getConfigurationManager())
} catch (Exception ex) {
LOG
error(
error getting ActionMapping
ex)
dispatcher
sendError(request
response
servletContext
HttpServletResponse
SC_INTERNAL_SERVER_ERROR
ex)
return;
}
if (mapping == null) {
String resourcePath = RequestUtils
getServletPath(request)
if (
equals(resourcePath) && null != request
getPathInfo()) {
resourcePath = request
getPathInfo()
}
if (serveStatic && resourcePath
startsWith(
/struts
)) {
String name = resourcePath
substring(
/struts
length())
findStaticResource(name
request
response)
} else {
//為一個普通的request
則通過
chain
doFilter(request
response)
}
return;
}
/**
*這個方法詢問ActionMapper是否需要調用某個Action來處理這個(request)請求
*如果ActionMapper決定需要調用某個Action
*FilterDispatcher則把請求的處理交給ActionProxy
dispatcher
serviceAction(request
response
servletContext
mapping)
} finally {
try {
ActionContextCleanUp
cleanUp(req)
} finally {
UtilTimerStack
pop(timerKey)
}
}
}
… …
}
在doFilter()方法中
將調用dispatcher
serviceAction
該方法如果找到相應的Action
將把用戶請求交給ActionProxy
serviceAction()代碼在Dispatcher
java中
如代碼
所示
代碼
Dispatcher類
public class Dispatcher {
…
/**
* 為mapping加載類
並調用相應的方法或者直接返回result
*
* 根據用戶請求的參數
建立Action上下文
* 根據指定的Action
名稱和包空間名稱
加載一個Action代理 ActionProxy
* 然後Action的相應方法將被執行
*/
public void serviceAction(HttpServletRequest request
HttpServletResponse response
ServletContext context
ActionMapping mapping) throws ServletException {
Map extraContext = createContextMap(request
response
mapping
context)
//如果存在一個值棧
則建立一個新的並復制以備Action使用
ValueStack stack = (ValueStack) request
getAttribute(ServletActionContext
STRUTS_VALUESTACK_KEY)
if (stack!= null) {
extraContext
put(ActionContext
VALUE_STACK
ValueStackFactory
getFactory()
createValueStack(stack))
}
String timerKey =
Handling request from Dispatcher
;
try {
UtilTimerStack
push(timerKey)
String namespace = mapping
getNamespace()
String name = mapping
getName()
String method = mapping
getMethod()
Configuration config = configurationManager
getConfiguration()
//FilterDispatcher把請求的處理交給ActionProxy
ActionProxy proxy = config
getContainer()
getInstance(ActionProxyFactory
class)
createActionProxy(namespace
name
extraContext
true
false)
proxy
setMethod(method)
request
setAttribute(ServletActionContext
STRUTS_VALUESTACK_KEY
proxy
getInvocation()
getStack())
//ActionMapping 直接返回一個result
if (mapping
getResult() != null) {
Result result = mapping
getResult()
result
execute(proxy
getInvocation())
} else {
proxy
execute()
}
if (stack != null) {
request
setAttribute(ServletActionContext
STRUTS_VALUESTACK_KEY
stack)
}
} catch (ConfigurationException e) {
LOG
error(
Could not find action or result
e)
sendError(request
response
context
HttpServletResponse
SC_NOT_FOUND
e)
} catch (Exception e) {
throw new ServletException(e)
} finally {
UtilTimerStack
pop(timerKey)
}
}
…
}
從上面代碼中可以看出來
Struts
用於處理用戶請求的Action實例
並不是用戶實現的業務控制器
而是Action代理
關於Action代理相關內容
讀者可以參考攔截器章節的介紹
From:http://tw.wingwit.com/Article/program/Java/ky/201311/27932.html