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","US");
}
//
修改
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);
}