Struts2源码详解 StrutsPrepareAndExecuteFilter

StrutsPrepareAndExecuteFilter struts2.1.3版本之后的struts框架的入口


public class StrutsPrepareAndExecuteFilter implements StrutsStatics, Filter {
protected PrepareOperations prepare;
protected ExecuteOperations execute;
protected List excludedPatterns = null;

public void init(FilterConfig filterConfig) throws ServletException {
InitOperations init = new InitOperations();
try {
FilterHostConfig config = new FilterHostConfig(filterConfig);
init.initLogging(config);
Dispatcher dispatcher = init.initDispatcher(config);
init.initStaticContentLoader(config, dispatcher);
//tong 这是一个命令模式的实现,通过config和dispatcher,初始化PrepareOperations,ExecuteOperations对象
prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);

postInit(dispatcher, filterConfig);
} finally {
init.cleanup();//tong 清空ActionContext
}

}

/**
* Callback for post initialization
*/
protected void postInit(Dispatcher dispatcher, FilterConfig filterConfig) {
}

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
//tong e1 main struts2里面的过滤器的web入口 struts2
HttpServletRequest request = (HttpServletRequest) req;//tong 把(servletRequest)转换成http协议
HttpServletResponse response = (HttpServletResponse) res;

try {// tong e1a 处理提交编码的问题,默认为utf-8 struts2
prepare.setEncodingAndLocale(request, response);//tong 设置request的默认编码和LOCAL
prepare.createActionContext(request, response);//tong 存放Action相关的web对象(创建ACTIONCONTEXT,并初始化Theadlocal)
prepare.assignDispatcherToThread();//tong 指派dispatcher给Theadlocal
if ( excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
chain.doFilter(request, response);//tong 如果是jpg,js等结尾的请求,那么系统就调用职责链模式的下一个职责链,对当前请求不作处理 struts2
} else {
request = prepare.wrapRequest(request);//tong 封装request
ActionMapping mapping = prepare.findActionMapping(request, response, true);
if (mapping == null) { //tong 如果映射不存在
boolean handled = execute.executeStaticResourceRequest(request, response);//tong 试图执行一个静态资源的请求
if (!handled) {
chain.doFilter(request, response);
}
} else {//tong 如果存在映射
execute.executeAction(request, response, mapping);//tong 执行action
}
}
} finally {
prepare.cleanupRequest(request);//tong 清除request的Threadlocal
}
}

public void destroy() {
prepare.cleanupDispatcher();//销毁
}
}

struts2的初始化

public class Dispatcher {

public void init(FilterConfig filterConfig) throws ServletException {
InitOperations init = new InitOperations();
try {
FilterHostConfig config = new FilterHostConfig(filterConfig);
init.initLogging(config);
Dispatcher dispatcher = init.initDispatcher(config);
init.initStaticContentLoader(config, dispatcher);
//tong 这是一个命令模式的实现,通过config和dispatcher,初始化PrepareOperations,ExecuteOperations对象
prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);

postInit(dispatcher, filterConfig);
} finally {
init.cleanup();//tong 清空ActionContext
}

}
}

解析struts2配置文件

private void init_TraditionalXmlConfigurations() {
//tong 首先读取web.xml中的config初始参数值
//tong 如果没有配置就使用默认的"struts-default.xml,struts-plugin.xml,struts.xml",
//tong 如果不想使用默认的名称,直接在web.xml中配置config初始参数即可
String configPaths = initParams.get("config");
if (configPaths == null) {
configPaths = DEFAULT_CONFIGURATION_PATHS;
}
String[] files = configPaths.split("\\s*[,]\\s*");
for (String file : files) {
//是否为xml文件
if (file.endsWith(".xml")) {
//tong 判断是不是xwork.xml文件,如果是就用XmlConfigurationProvider单独解析
if ("xwork.xml".equals(file)) {
configurationManager.addConfigurationProvider(new XmlConfigurationProvider(file, false));
} else {//tong 如果不是就解析struts2配置文件(1.struts-default.xml,2.struts-plugin.xml,3.struts.xml)
configurationManager.addConfigurationProvider(new StrutsXmlConfigurationProvider(file, false, servletContext));
}
} else {
throw new IllegalArgumentException("Invalid configuration file name");
}
}
}

初始化完成 调用doFilter方法处理请求

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
//tong e1 main struts2里面的过滤器的web入口 struts2
HttpServletRequest request = (HttpServletRequest) req;//tong 把(servletRequest)转换成http协议
HttpServletResponse response = (HttpServletResponse) res;

try {// tong e1a 处理提交编码的问题,默认为utf-8 struts2
prepare.setEncodingAndLocale(request, response);//tong 设置request的默认编码和LOCAL
prepare.createActionContext(request, response);//tong 存放Action相关的web对象(创建ACTIONCONTEXT,并初始化Theadlocal)
prepare.assignDispatcherToThread();//tong 指派dispatcher给Theadlocal
if ( excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
chain.doFilter(request, response);//tong 如果是jpg,js等结尾的请求,那么系统就调用职责链模式的下一个职责链,对当前请求不作处理 struts2
} else {
request = prepare.wrapRequest(request);//tong 封装request
ActionMapping mapping = prepare.findActionMapping(request, response, true);
if (mapping == null) { //tong 如果映射不存在
boolean handled = execute.executeStaticResourceRequest(request, response);//tong 试图执行一个静态资源的请求
if (!handled) {
chain.doFilter(request, response);
}
} else {//tong 如果存在映射
execute.executeAction(request, response, mapping);//tong 执行action
}
}
} finally {
prepare.cleanupRequest(request);//tong 清除request的Threadlocal
}
}


createActionContext方法


public ActionContext createActionContext(HttpServletRequest request, HttpServletResponse response) {
ActionContext ctx;
Integer counter = 1;
Integer oldCounter = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);
if (oldCounter != null) {
counter = oldCounter + 1;
}

ActionContext oldContext = ActionContext.getContext();
if (oldContext != null) {
// detected existing context, so we are probably in a forward
ctx = new ActionContext(new HashMap(oldContext.getContextMap()));
} else {//tong 值栈,将信息保存到OGNL的值栈中
ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
stack.getContext().putAll(dispatcher.createContextMap(request, response, null, servletContext));
ctx = new ActionContext(stack.getContext());//tong createContextMap方法:将所有的servlet对象全部用Map封装起来,实现了struts2的Action与servlet解耦
}
request.setAttribute(CLEANUP_RECURSION_COUNTER, counter);
ActionContext.setContext(ctx);
return ctx;
}


assignDispatcherToThread()

ThreadLocal解决了struts2线程安全问题

然后创建了Action代理(createActionProxy),通过代理调用了调度器(inovke())
运用了责任链模式通过调度器去调用一个个拦截器,拦截器执行完,到Action处理请求。

调用destroy()进行销毁。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值