很多时候,为什么感觉一本书很难啃,俩字,抽象,所谓的抽象,不过是自己对这些概念不甚理解,本来程序 软件设计的东西就是从现实里抽取的,大不了我们还原到里面就是。
在这里,我拿去饭店吃饭做比,当http这个客人受到前台的接待,前台会根据你的请求将房间号的包间给你,你过去,这个包间就是一个servlet,然后通过菜单点菜,菜单就是servlet里方法的注解,映射了每道菜制作的过程,无须对展示层展示,只需要客人看到最终的菜肴即可,这样也就达到了隔离安全的效果,餐桌就是一个模板,每个不同的请求返回的结果可以在这个模板里集中展示,modelandview与view解析器也派上用场了。
再仔细的分解这个过程,当http受接待的时候,会受到这个饭店的配置限制吧,也就是你的web.xml就要设置为此饭店,也就是容器了,当你进入饭店的时候,拦截处理,往往会确认一下你是否预定等一些事宜,这里拿Struts2的dispatcher来说明,通过对这些请求进行预处理,这里是PrepareOperations的对象来处理的,其实其也就是个代理对象,正儿八经实现的还是dispatcher本身,由其进行转发处理,这里就别贴源码了,可以自己打开ide自己追着看,想想前台服务员是不是可以各种换,然后其执行的任务是不是始终都一样,通过对客人提供的信息进行处理封装,就像房间号和你放在一个Map中一样,同样,也可以在这里看到Struts和XWork融合的地方,就是dispatcher的serviceAction方法可以看到这里是是Dispatcher对象的核心逻辑调度方法,起到了中转站的作用
* @since 2.3.17
*/
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping)
throws ServletException {
Map<String, Object> extraContext = createContextMap(request, response, mapping);
// If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
boolean nullStack = stack == null;
if (nullStack) {
ActionContext ctx = ActionContext.getContext();
if (ctx != null) {
stack = ctx.getValueStack();
}
}
if (stack != null) {
extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack));
}
String timerKey = "Handling request from Dispatcher";
try {
UtilTimerStack.push(timerKey);
String namespace = mapping.getNamespace();
String name = mapping.getName();
String method = mapping.getMethod();
ActionProxy proxy = getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, method, extraContext, true, false);
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
// if the ActionMapping says to go straight to a result, do it!
if (mapping.getResult() != null) {
Result result = mapping.getResult();
result.execute(proxy.getInvocation());
} else {
proxy.execute();
}
// If there was a previous value stack then set it back onto the request
if (!nullStack) {
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
}
} catch (ConfigurationException e) {
logConfigurationException(request, e);
sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e);
} catch (Exception e) {
if (handleException || devMode) {
sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
} else {
throw new ServletException(e);
}
} finally {
UtilTimerStack.pop(timerKey);
}
}