Struts1.x的簡單解讀
1
、
Struts1.x
簡單配置
a )、配置 struts
?????? * 拷貝 struts lib 下的所有 jar 到 WEB-INF/lib 下
?????? * 修改 web.xml 文件,配置 ActionServlet
?????? * 提供 struts-config.xml 文件
??????
b) 、創建登錄項目
?????? * 創建 jsp 頁面( login.jsp,login_success.jsp,login_error.jsp ) ?
?????? * 創建 LoginActionForm.java
?????? * 創建 LoginAction.java
?????? * 配置 struts-config.xml 文件
2
、
I18N
問題
?????? 首先創建國際化資源文件: MessageResources_zh_CN.properties ,如此格式,
然后在 Struts-config.xml 中配置一個 Action 處理,該編碼問題,并做如下代碼:
?????? ?????? String lang = request.getParameter("lang");// 取得指定的語言
????????????? Locale currentLocale = Locale.getDefault();//
得到本地
Locale
?????????????
????????????? if("zh".equals(lang)){
???????????????????? currentLocale = new Locale("zh","CN");
????????????? }else if("en".equals(lang)){
???????????????????? currentLocale = new Locale("en","
????????????? }
????????????? // 修改 session 中 Globals.LOCALE_KEY
????????????? request.getSession().setAttribute(Globals.LOCALE_KEY, currentLocale);
?????????????
3
、采用
DispathAction
?????? * 如果覆寫 DispathAction 中的 execute 方法,必須顯示的用 super 調用 execute 方法
?????? * parameter 參數值不能是 execute 或 perform
?????? * 了解 <action> 標簽中的 parameter 的含義
?????? * 了解 DispathAction 中的 unspecified 方法的含義
4
、學會使用
FormBean
?????? 在配置文件中配置的 ActionForm 在解析 ActionMapping 時,會以 Action 的 name 為 key ,然后在 HttpSession 中存儲該 ActionForm 的值,那么我們在整個會話中都會得到這個 Form ,而且這個 Form 在每次請求的時候都會更新。
5
、
ActionServlet
初始化方法
??
public
void
init()
throws
ServletException {
???????
final
String configPrefix =
"config/"
;
???????
final
int
configPrefixLength = configPrefix.length() - 1;
???????
// Wraps the entire initialization in a try/catch to better handle
???????
// unexpected exceptions and errors to provide better feedback
???????
// to the developer
???????
try
{
//
初始化我們系統的資源信息綁定
??????????? initInternal();
?????????
??//
初始化控制器的字符集轉換信息,通過配置
web.xml
中的
convertNull
參數來進行數據類型的轉換。通過注冊轉換器來實現。
initOther();?
//
初始化我們當前請求的
Servlet
控制器
?????????
??initServlet();
//
解析配置文件
web.xml
文件中的
chainConfig
初始化參數去配置在
CatalogFactory
中默認的
org.apache.commons.chain.Catalog
。
??????????? initChain();
//
在當前的
Servlet
上下文中使用
Globals.ACTION_SERVLET_KEY
保存當前的
ActionServlet
。
??????????? getServletContext().setAttribute(Globals.
ACTION_SERVLET_KEY
,
this
);
//
初始化
ModuleConfig
的模版工廠
??????????? initModuleConfigFactory();
???????
????//
初始化當前需要的
ModuleConfig,
即開始初始化
struts-config.xml
??????????? ModuleConfig moduleConfig = initModuleConfig(
""
,
config
);
??????
??? //
初始化配置文檔中的國際化資源信息,并將其存入當前的
ServletCotext
中。
??????????? initModuleMessageResources(moduleConfig);
??????
??? //
初始化配置文檔中的插件
??????????? initModulePlugIns(moduleConfig);
?????????? //
初始化
FormBeans
并建起存入
moduleConfig
中,其實是保存在當前的
HttpSession
中,每次請求替換一次該
FormBeans
??????????? initModuleFormBeans(moduleConfig);
//
初始化全局化的
Forward
將
Forward
保存在當前的
ActionConfig
或者
moduleConfig
中
??????????? initModuleForwards(moduleConfig);
//
初始化全局
Exception
將
Exception
保存在當前的
ActionConfig
或者
moduleConfig
中
??????????? initModuleExceptionConfigs(moduleConfig);
//
初始化
Action
,將當前
ActionConfig
保存在
moduleConfig
中,用路徑做為
key
??????????? initModuleActions(moduleConfig);
//
凍結當前配置模版,任何修改將會導致
IllegalStateException
。
??????????? moduleConfig.freeze();
//
取得當前
Application
的
web.xml
中的所有的初始化參數,然后在解析配置文件
??????????? Enumeration names = getServletConfig().getInitParameterNames();
???????????
while
(names.hasMoreElements()) {
??????????????? String name = (String) names.nextElement();
???????????????
if
(!name.startsWith(configPrefix)) {
???????????????????
continue
;
?
?????????????? }
??????????????? String prefix = name.substring(configPrefixLength);
??????????????? moduleConfig =
??????????????????? initModuleConfig(prefix,
??????????????????????? getServletConfig().getInitParameter(name));
??????????????? initModuleMessageResources(moduleConfig);
??????????????? initModulePlugIns(moduleConfig);
??????????????? initModuleFormBeans(moduleConfig);
??????????????? initModuleForwards(moduleConfig);
??????????????? initModuleExceptionConfigs(moduleConfig);
??????????????
?initModuleActions(moduleConfig);
??????????????? moduleConfig.freeze();
??????????? }
//
保持模版前綴的字符串數組在
ServletContext
中。使用
Globals.MODULE_PREFIXES_KEY
???????????
this
.initModulePrefixes(
this
.getServletContext());
//
溫柔的釋放我們創建的
ConfigDigester
???????????
this
.destroyConfigDigester();
??????? }
catch
(UnavailableException ex) {
???????????
throw
ex;
??????? }
catch
(Throwable t) {
???????????
// The follow error message is not retrieved from internal message
???????????
// resources as they may not have been able to have been
???????????
// initialized
???????????
log
.error(
"Unable to initialize Struts ActionServlet due to an "
??????????????? +
"unexpected exception or error thrown, so marking the "
??????????????? +
"servlet as unavailable.? Most likely, this is due to an "
??????????????? +
"incorrect or missing library dependency."
, t);
??????????
?
throw
new
UnavailableException(t.getMessage());
??????? }
??? }
??????
6
、
Struts
請求處理流程
??????
?????? 1
)、請求通過
doGet
或
doPost
方法委托給
ActionServlet
的
process
方法。
???
??? //
執行標準的請求處理方法,并創建相應的回復
??????
protected
void
process(HttpServletRequest request,
???????
??????? HttpServletResponse response)
??????? ??????? throws IOException, ServletException {
??????
???
??? //
根據請求選擇相應的模版信息,而且添加相應的請求屬性到當前的請求
ModuleUtils.getInstance().selectModule(request, getServletContext());
???
??? //
為選中的模版,選擇相應的模版配置信息對象
??????? ModuleConfig config = getModuleConfig(request);
???
??? //
根據當前的模版配置信息,返回一個請求處理器,如果沒有的話則返回
null
,該方法不會創建
RequestProcessor
??????? RequestProcessor processor = getProcessorForModule(config);
?????? //
如果該模版的請求處理器為
null
,則使用模版信息創建一個
RequestProcessor
???????
if
(processor ==
null
) {
??????????? processor = getRequestProcessor(config);
???
????}
?????? //
使用請求處理器來處理當前的請求,
RequestProcessor
以及
process
方法是整個
Struts
的核心對象和方法
??????? processor.process(request, response);
}
2
)、
RequestProcessor
的
process
方法
???
public
void
process(HttpServletRequest request, HttpServletResponse response)
???????
throws
IOException, ServletException {
??????? // Wrap multipart requests with a special wrapper
(用一個特效的包裝器來包裝多媒體請求,如果當前請求不是多媒體的則方法原理的請求對象)
??????? request = processMultipart(request);
???????
// Identify the path component we will use to select a mapping
?????? //
根據請求
URI
,選擇一個
Action Mapping
去分派請求,如果沒有則報錯或結束方法
??????? String path = processPath(request, response);
???????
if
(path ==
null
) {
???????????
return
;
??????? }
???????
if
(
log
.isDebugEnabled()) {
???????????
log
.debug(
"Processing a '"
+ request.getMethod() +
"' for path '"
??????????????? + path +
"'"
);
??????? }
???????
// Select a Locale
(地點)
for the current user if requested
??????? processLocale(request, response);
???????
// Set the content type and no-caching headers if requested
??????? processContent(request, response);
??????? processNoCache(request, response);
???????
// General purpose preprocessing
(預處理)
hook
,
true
則表示正常執行下面語句,否則表示已經完成處理
???????
if
(!processPreprocess(request, response)) {
???????????
return
;
??????? }
??????
//
從
session
中移除或者添加修改
Grobel.MESSAGE_KEY
或
Grobel.ERROR_KEY
???????
this
.processCachedMessages(request, response);
??????
??????? // Identify the mapping for this request
,根據
path
為
request
選擇一個
ActionMapping
,來訪問相應的
Action
。
ActionMapping
提供給
RequestProcessor
對于
Action
的各種處理信息。
??????? ActionMapping mapping = processMapping(request, response, path);
???????
if
(mapping ==
null
) {
???????????
return
;
??????? }
???????
// Check for any role required to perform this action
???????
if
(!processRoles(request, response, mapping)) {
???????????
return
;
??????? }
???????
// Process any ActionForm bean related to
(涉及)
this request
??????? ActionForm form = processActionForm(request, response, mapping);
//
根據
request
中的請求參數,組裝特殊的
ActionForm
??????? processPopulate(request, response, form, mapping);
??????? // 如果這個請求沒有取消而且這個請求的 ActionMapping 沒有取消驗證,調用指定的 ActionForm 中的 validate 方法,然后轉發到 input 路徑指定的頁面也就是錯誤發生的頁面。返回 true 我們將繼續處理,否則我們已經被控制轉發到 input 表單頁面中。
???????
try
{
???????????
if
(!processValidate(request, response, form, mapping)) {
???????????????
return
;
??????????? }
??????? }
catch
(InvalidCancelException e) {
//
詢問我們的異常處理器去處理異常。有調用的
ExceptionHandler
返回
ActionForward
實例
ActionForward forward = processException(request, response, e, form, mapping);
//
根據指定的機制轉發或者重定向到指定的目的地。
??????????? processForwardConfig(request, response, forward);
???????????
return
;
??????? }
catch
(IOException e) {
???????????
throw
e;
??????? }
catch
(ServletException e) {
???????????
throw
e;
??????? }
???????
// Process a forward or include specified by this mapping
???????
if
(!processForward(request, response, mapping)) {
???????????
return
;
??????? }
???????
if
(!processInclude(request, response, mapping)) {
???????????
return
;
??????? }
???????
//
返回一個用于處理當前請求的
ActionForm
實例,如果必要的話返回一個新實例
??????? Action action = processActionCreate(request, response, mapping);
???????
if
(action ==
null
) {
???????????
return
;
??????? }
??????? //
詢問指定的
Action
實例去處理當前的請求。根據調用的
Action
返回
ActionForward
實例用作以后的處理。
??????? ActionForward forward =
??????????? processActionPerform(request, response, action, form, mapping);
???? ???// 根據指定的機制轉發或者重定向到指定的目的地。
??????? processForwardConfig(request, response, forward);
??? }
posted on 2009-11-04 21:13 vagasnail 閱讀(292) 評論(0) 編輯 收藏 所屬分類: Java框架