/*
* $Id: DispatchAction.java 384089 2006-03-08 01:50:52Z niallp $
*
* Copyright 2001-2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.struts.actions;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.util.MessageResources;
/**
* <p>An abstract <strong>Action</strong> that dispatches to a public
* method that is named by the request parameter whose name is specified
* by the <code>parameter</code> property of the corresponding
* ActionMapping. This Action is useful for developers who prefer to
* combine many similar actions into a single Action class, in order to
* simplify their application design.</p>
*
* <p>To configure the use of this action in your
* <code>struts-config.xml</code> file, create an entry like this:</p>
*
* <code>
* <action path="/saveSubscription"
* type="org.apache.struts.actions.DispatchAction"
* name="subscriptionForm"
* scope="request"
* input="/subscription.jsp"
* parameter="method"/>
* </code>
*
* <p>which will use the value of the request parameter named "method"
* to pick the appropriate "execute" method, which must have the same
* signature (other than method name) of the standard Action.execute
* method. For example, you might have the following three methods in the
* same action:</p>
* <ul>
* <li>public ActionForward delete(ActionMapping mapping, ActionForm form,
* HttpServletRequest request, HttpServletResponse response)
* throws Exception</li>
* <li>public ActionForward insert(ActionMapping mapping, ActionForm form,
* HttpServletRequest request, HttpServletResponse response)
* throws Exception</li>
* <li>public ActionForward update(ActionMapping mapping, ActionForm form,
* HttpServletRequest request, HttpServletResponse response)
* throws Exception</li>
* </ul>
* <p>and call one of the methods with a URL like this:</p>
* <code>
* http://localhost:8080/myapp/saveSubscription.do?method=update
* </code>
*
* <p><strong>NOTE</strong> - All of the other mapping characteristics of
* this action must be shared by the various handlers. This places some
* constraints over what types of handlers may reasonably be packaged into
* the same <code>DispatchAction</code> subclass.</p>
*
* <p><strong>NOTE</strong> - If the value of the request parameter is empty,
* a method named <code>unspecified</code> is called. The default action is
* to throw an exception. If the request was cancelled (a <code>html:cancel</code>
* button was pressed), the custom handler <code>cancelled</code> will be used instead.
* You can also override the <code>getMethodName</code> method to override the action's
* default handler selection.</p>
*
* @version $Rev: 384089 $ $Date: 2006-03-08 01:50:52 +0000 (Wed, 08 Mar 2006) $
*/
public abstract class DispatchAction extends Action {
// ----------------------------------------------------- Instance Variables
/**
* The Class instance of this <code>DispatchAction</code> class.
*/
protected Class clazz = this.getClass();
/**
* Commons Logging instance.
*/
protected static Log log = LogFactory.getLog(DispatchAction.class);
/**
* The message resources for this package.
*/
protected static MessageResources messages =
MessageResources.getMessageResources
("org.apache.struts.actions.LocalStrings");
/**
* The set of Method objects we have introspected for this class,
* keyed by method name. This collection is populated as different
* methods are called, so that introspection needs to occur only
* once per method name.
*/
protected HashMap methods = new HashMap();
/**
* The set of argument type classes for the reflected method call. These
* are the same for all calls, so calculate them only once.
*/
protected Class[] types =
{
ActionMapping.class,
ActionForm.class,
HttpServletRequest.class,
HttpServletResponse.class};
// --------------------------------------------------------- Public Methods
/**
* Process the specified HTTP request, and create the corresponding HTTP
* response (or forward to another web component that will create it).
* Return an <code>ActionForward</code> instance describing where and how
* control should be forwarded, or <code>null</code> if the response has
* already been completed.
*
* @param mapping The ActionMapping used to select this instance
* @param form The optional ActionForm bean for this request (if any)
* @param request The HTTP request we are processing
* @param response The HTTP response we are creating
*
* @exception Exception if an exception occurs
*/
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
if (isCancelled(request)) {
ActionForward af = cancelled(mapping, form, request, response);
if (af != null) {
return af;
}
}
// Get the parameter. This could be overridden in subclasses.
String parameter = getParameter(mapping, form, request, response);
// Get the method's name. This could be overridden in subclasses.
String name = getMethodName(mapping, form, request, response, parameter);
// Prevent recursive calls
if ("execute".equals(name) || "perform".equals(name)){
String message =
messages.getMessage("dispatch.recursive", mapping.getPath());
log.error(message);
throw new ServletException(message);
}
// Invoke the named method, and return the result
return dispatchMethod(mapping, form, request, response, name);
}
/**
* Method which is dispatched to when there is no value for specified
* request parameter included in the request. Subclasses of
* <code>DispatchAction</code> should override this method if they wish
* to provide default behavior different than throwing a ServletException.
*/
protected ActionForward unspecified(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
String message =
messages.getMessage(
"dispatch.parameter",
mapping.getPath(),
mapping.getParameter());
log.error(message);
throw new ServletException(message);
}
/**
* Method which is dispatched to when the request is a cancel button submit.
* Subclasses of <code>DispatchAction</code> should override this method if
* they wish to provide default behavior different than returning null.
* @since Struts 1.2.0
*/
protected ActionForward cancelled(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
return null;
}
// ----------------------------------------------------- Protected Methods
/**
* Dispatch to the specified method.
* @since Struts 1.1
*/
protected ActionForward dispatchMethod(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response,
String name) throws Exception {
// Make sure we have a valid method name to call.
// This may be null if the user hacks the query string.
if (name == null) {
return this.unspecified(mapping, form, request, response);
}
// Identify the method object to be dispatched to
Method method = null;
try {
method = getMethod(name);
} catch(NoSuchMethodException e) {
String message =
messages.getMessage("dispatch.method", mapping.getPath(), name);
log.error(message, e);
String userMsg =
messages.getMessage("dispatch.method.user", mapping.getPath());
throw new NoSuchMethodException(userMsg);
}
ActionForward forward = null;
try {
Object args[] = {mapping, form, request, response};
forward = (ActionForward) method.invoke(this, args);
} catch(ClassCastException e) {
String message =
messages.getMessage("dispatch.return", mapping.getPath(), name);
log.error(message, e);
throw e;
} catch(IllegalAccessException e) {
String message =
messages.getMessage("dispatch.error", mapping.getPath(), name);
log.error(message, e);
throw e;
} catch(InvocationTargetException e) {
// Rethrow the target exception if possible so that the
// exception handling machinery can deal with it
Throwable t = e.getTargetException();
if (t instanceof Exception) {
throw ((Exception) t);
} else {
String message =
messages.getMessage("dispatch.error", mapping.getPath(), name);
log.error(message, e);
throw new ServletException(t);
}
}
// Return the returned ActionForward instance
return (forward);
}
/**
* <p>Returns the parameter value.</p>
*
* @param mapping The ActionMapping used to select this instance
* @param form The optional ActionForm bean for this request (if any)
* @param request The HTTP request we are processing
* @param response The HTTP response we are creating
* @return The <code>ActionMapping</code> parameter's value
* @throws Exception if the parameter is missing.
*/
protected String getParameter(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// Identify the request parameter containing the method name
String parameter = mapping.getParameter();
if (parameter == null) {
String message =
messages.getMessage("dispatch.handler", mapping.getPath());
log.error(message);
throw new ServletException(message);
}
return parameter;
}
/**
* Introspect the current class to identify a method of the specified
* name that accepts the same parameter types as the <code>execute</code>
* method does.
*
* @param name Name of the method to be introspected
*
* @exception NoSuchMethodException if no such method can be found
*/
protected Method getMethod(String name)
throws NoSuchMethodException {
synchronized(methods) {
Method method = (Method) methods.get(name);
if (method == null) {
method = clazz.getMethod(name, types);
methods.put(name, method);
}
return (method);
}
}
/**
* Returns the method name, given a parameter's value.
*
* @param mapping The ActionMapping used to select this instance
* @param form The optional ActionForm bean for this request (if any)
* @param request The HTTP request we are processing
* @param response The HTTP response we are creating
* @param parameter The <code>ActionMapping</code> parameter's name
*
* @return The method's name.
* @since Struts 1.2.0
*/
protected String getMethodName(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response,
String parameter)
throws Exception {
// Identify the method name to be dispatched to.
// dispatchMethod() will call unspecified() if name is null
return request.getParameter(parameter);
}
}
分享到:
相关推荐
11.2.6 DispatchAction(多动作控制器) 11.3 利用Struts实现用户登录的示例 11.6.1 编写实现登录的页面login.jsp 11.6.2 编写存储登录用户信息的类User.java 11.6.3 编写控制器LoginAction.java 11.6.4 配置Struts...
11.2.6 DispatchAction(多动作控制器) 11.3 利用Struts实现用户登录的示例 11.6.1 编写实现登录的页面login.jsp 11.6.2 编写存储登录用户信息的类User.java 11.6.3 编写控制器LoginAction.java 11.6.4 配置Struts...
11.2.6 DispatchAction(多动作控制器) 11.3 利用Struts实现用户登录的示例 11.6.1 编写实现登录的页面login.jsp 11.6.2 编写存储登录用户信息的类User.java 11.6.3 编写控制器LoginAction.java 11.6.4 配置Struts...
11.2.6 DispatchAction(多动作控制器) 11.3 利用Struts实现用户登录的示例 11.6.1 编写实现登录的页面login.jsp 11.6.2 编写存储登录用户信息的类User.java 11.6.3 编写控制器LoginAction.java 11.6.4 配置Struts...
Struts是Java Web开发中的一款经典MVC框架,它的核心组件之一是DispatchAction,这个组件在处理用户请求时起到了至关重要的作用。DispatchAction是Struts提供的一个可扩展的Action类,它允许开发者将一个单一的...
1. **创建子类**:首先,你需要创建一个继承自` DispatchAction `的Java类。在这个类中,你可以定义自己的业务逻辑方法,比如`executeSave()`、`executeDelete()`等。 ```java public class MyDispatchAction ...
总之,Struts DispatchAction是Java Web开发中一种有效的请求分发机制,它允许在一个Action类中组织和管理多个业务处理方法,提高了代码的可读性和可维护性。然而,随着技术的发展,如Struts2的出现,开发者可以选择...
### DispatchAction、LookupDispatchAction、SwitchAction 的应用详解 #### 一、DispatchAction 的应用 **DispatchAction** 是 Struts 框架中一个非常有用的类,它位于 `org.apache.struts.actions` 包中。其核心...
- `DepartmentAction.java`: 实现DispatchAction,包括`executeAdd()`, `executeDelete()`, `executeUpdate()`等方法。 - `struts-config.xml`: 配置DispatchAction及其映射规则。 - `department.jsp`: 显示部门...
本文总结了 Java 面试中的一些常见问题,涵盖了 Ajax 的原理、优缺点、 DispatchAction 和 Action 的区别等知识点。 Ajax 的原理 Ajax 是一种异步请求技术,通过 XmlHttpRequest 对象来向服务器发送异步请求,从...
Struts框架是Java Web开发中一个非常重要的MVC(Model-View-Controller)框架,它为开发者提供了一种结构化的方式来组织和管理应用程序。在早期的Struts版本中,`DispatchAction`类是一个核心组件,它允许我们通过...
然而,当开发者尝试使用反射调用一个不存在的方法时,便会遇到`java.lang.NoSuchMethodException`异常。本文将深入探讨此异常,特别是它在服务器端Java应用中的常见场景——例如Struts框架——并提供详细的解决方案...
a onclick="javascript:window.open(encodeURI(encodeURI('./DispatchAction.do?ename=FKRY0001&code_type=中文参数')))"测试/a 或者单独对参数进行二次编码: var code_type = "中文参数"; code_type = encodeURI...
Struts 是一个经典的Java Web开发框架,用于构建企业级的MVC(模型-视图-控制器)应用程序。在Struts框架中,`DispatchAction`是一个关键组件,它扮演着控制器的角色,负责处理用户请求并调用相应的业务逻辑。在本篇...
14. 简述synchronized和java.util.concurrent.locks.Lock的异同 ? 11 15. 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 11 16. abstract class和interface有什么区别? 12...
Struts框架是Java Web开发中常用的一个MVC(Model-View-Controller)框架,它极大地简化了企业级应用的开发工作。DispatchAction是Struts框架中的一个动作类,用于处理用户的请求并转发到相应的业务逻辑。在这个场景...
Struts是Java Web开发中的一款经典MVC框架,它的出现极大地简化了企业级应用的构建。在本项目中,我们关注的是"Struts+Oracle实现DispatchAction类",这是一个将Struts框架与Oracle数据库结合使用,以实现业务逻辑...
Struts框架是Java Web开发中的一个关键组件,属于SSH(Struts、Spring、Hibernate)三大框架之一。它提供了一种模型-视图-控制器(MVC)架构模式,帮助开发者组织和管理应用程序的业务逻辑、数据处理和用户界面。...
- **BBS在线论坛管理系统**:主要负责用户管理模块,运用Hibernate处理数据,Struts的DispatchAction处理请求,JavaScript前端验证,体现了前后端交互和用户管理功能的实现。 通过这些项目,工程师不仅提升了技术...
SSH整合是Java Web开发中的一种常见技术组合,它由Spring、Struts和Hibernate三个框架组成。这个"SSH整合继承DispatchAction的简单例子"是一个演示如何将这三个框架集成在一起,并利用Struts的DispatchAction来实现...