1.当客户端有请求过来,Web容器把它传给Struts2的FilterDispather;如果是.html
等请求,FilterDispacther直接把调用传给Servlet的FilterChain,如果是Action
请求,则把调用传递给FilterDispachter中dispatcher对象的ServiceAction方法.
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 {
// FIXME: this should be refactored better to not duplicate work with the action invocation
ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
ActionContext ctx = new ActionContext(stack.getContext());
ActionContext.setContext(ctx);
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) {
// there is no action in this request, should we look for a static resource?
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 {
// this is a normal request, let it pass through
chain.doFilter(request, response);
}
// The framework did its job here
return;
}
dispatcher.serviceAction(request, response, servletContext, mapping);
} finally {
try {
ActionContextCleanUp.cleanUp(req);
} finally {
UtilTimerStack.pop(timerKey);
}
}
}
2.在dispatcher方法中,首先创建ActionProxy对象,在ActionProxy对象中创建DefaultActionInvocation对象(此对象包括获取Action,Result的方法,并包括Interceptors列表)
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
ActionMapping mapping) throws ServletException {
Map<String, Object> extraContext = createContextMap(request, response, mapping, context);
// 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);
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();
Configuration config = configurationManager.getConfiguration();
ActionProxy proxy = config.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 (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) {
sendError(request, response, context, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
} finally {
UtilTimerStack.pop(timerKey);
}
}
3.在上面准备工作完成后,调用ActionProxy的execute()方法,它调用
DefaultActionInvocation对象的invoke方法,此方法开启Interceptors链的调用,然后调Action的excute(或其它)方法,最后调用Result的excute方法, 并把执行结果返回给客户端.
public String invoke() throws Exception {
String profileKey = "invoke: ";
try {
UtilTimerStack.push(profileKey);
if (executed) {
throw new IllegalStateException("Action has already executed");
}
if (interceptors.hasNext()) {
final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next();
//UtilTimerStack.profile("interceptor: "+interceptor.getName(),
// new UtilTimerStack.ProfilingBlock<String>() {
// public String doProfiling() throws Exception {
resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
// return null;
// }
//});
} else
{
resultCode = invokeActionOnly();
}
// this is needed because the result will be executed, then control will return to the Interceptor, which will
// return above and flow through again
if (!executed) {
if (preResultListeners != null) {
for (Iterator iterator = preResultListeners.iterator();
iterator.hasNext();) {
PreResultListener listener = (PreResultListener) iterator.next();
String _profileKey="preResultListener: ";
try {
UtilTimerStack.push(_profileKey);
listener.beforeResult(this, resultCode);
}
finally {
UtilTimerStack.pop(_profileKey);
}
}
}
// now execute the result, if we're supposed to
if (proxy.getExecuteResult()) {
executeResult();
}
executed = true;
}
return resultCode;
}
finally {
UtilTimerStack.pop(profileKey);
}
}
分享到:
相关推荐
### Struts 2 Action 动态方法调用详解 #### 一、引言 在Struts 2框架中,Action动态方法调用是一项非常实用的功能。它允许开发者在一个Action类中定义多个处理方法,而不仅仅局限于传统的`execute()`方法。这种...
在Struts2中,动态方法调用(Dynamic Method Invocation,DMI)是一种特性,允许我们通过URL直接调用Action类的方法,而无需在配置文件中显式指定。这在某些情况下提供了更大的灵活性。 在Struts2的动态方法调用中...
在Struts2中,Action是业务逻辑处理的核心,而通配符的使用则是Struts2框架中一种灵活的配置方式,允许我们以更简洁的方式调用同一个Action中的不同方法。下面我们将深入探讨如何利用Struts2的通配符来实现这一功能...
总结,Struts2调用存储过程涉及数据库连接、DAO设计、Action控制和视图展示等多个环节。通过合理配置和编程,我们可以有效地利用存储过程提升应用的效率和灵活性。"Struts2_crud2.0_Procedure"示例提供了具体实现,...
Struts2的配置文件(struts.xml)可以通过通配符来定义Action,使得一个Action能够处理多个方法调用。例如,我们可以定义一个Action,然后使用不同的参数值来调用不同的Action方法。这样可以减少Action的数量,简化...
利用Struts 2框架创建一个web项目chap2_e22,实现用户登录过程。具体要求是在loginAction类中分别用login()和registered()处理用户登录和注册的过程,分别创建login.jsp和register.jsp两个页面实现登录和注册的...
在Struts2框架中,经常需要实现Action之间的跳转,并在跳转过程中传递必要的参数。这种需求在实际开发中非常常见,尤其是在需要根据用户的不同操作来调用不同的业务逻辑时。下面将详细介绍如何在Struts2中实现Action...
默认情况下,Struts2会调用Action类中的execute方法来处理请求。但是,通过`method`属性,我们可以指定不同的方法对应不同的Action,这样可以实现一个类中多个方法的映射,提高代码复用性。例如: ```xml <action ...
在Struts2的配置文件(通常为struts.xml或struts.properties)中,我们定义Action的映射规则,包括请求路径、方法调用以及结果视图等。默认情况下,一个Action类对应一个请求URL,但通过特定配置,可以让一个Action...
综上所述,"struts2+oracle过程调用"涉及了Struts2框架中Action类与数据库的交互,Oracle数据库的管理,以及PL/SQL过程的使用。这个主题涵盖了Web开发中的后端业务逻辑处理,以及数据库层面的数据操作,对于开发高效...
这个案例“struts014”很可能展示了如何在Struts2中实现异步调用来处理耗时操作,如数据库查询或复杂计算。 异步调用的基本概念是,客户端(通常是Web浏览器)发起一个请求,服务器不立即返回结果,而是启动一个...
- **Interceptor**(拦截器):拦截器是Struts2的核心组件,它们按照预定义的顺序对Action的调用进行拦截,实现如日志记录、权限验证、事务管理等功能。 2. **配置方式**: - **XML配置**:传统的Struts2配置通常...
根据提供的信息,我们可以推断出这是一本关于Struts 2框架的书籍——《Struts 2实战 Struts 2 in action 的中文版》。本书主要介绍了Struts 2框架的相关概念、工作原理以及实际应用案例等内容。接下来,我们将根据...
Struts2 动态调用 Action 指定方法及默认 Action 配置 Struts2 框架中,一个 Action 可以包含多个处理逻辑,而不是只有一个 execute() 方法。在实际开发中,我们经常需要在一个 Action 中实现多个处理逻辑,这样...
2. **拦截器(Interceptors)**:Struts2的拦截器机制允许开发者定义一系列处理请求的规则,如日志记录、权限检查、事务管理等,这些规则可以在Action执行前后被调用,提高了代码的复用性和模块化。 3. **结果类型...
### JS调用Struts中的Action #### 背景与概念 在Web开发中,JavaScript(简称JS)作为客户端脚本语言,常被用来增强用户体验、处理表单验证等前端任务。而Struts框架则是Java Web开发中常用的一个MVC(Model-View-...
Struts2会根据URL中的部分替换通配符,并尝试调用Action类中的方法。如果找不到与之匹配的方法,Struts2将会回退到默认的执行方法(通常是`execute`)。 为了更高效地利用这一特性,我们需要遵循以下几点: 1. 方法...
3. **FilterDispatcher**:Struts2的核心控制器,负责拦截所有请求,解析并调用相应的Action,然后根据Action的结果进行响应。 4. **配置文件**:Struts2的配置通常存储在XML文件中,包括对Action、拦截器、结果...
ajaxt json 调用struts2 action的实例(myeclipse 直接导入运行) 学习点: 1;怎样在页面用ajax调用struts2的action 2;怎样对struts进行配置 3;ajax的运行历程 最简单明了的实例,清晰的帮你弄清上述概念,运行...