/*
* $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);
}
}
分享到:
相关推荐
主要介绍了深入解析Java的Struts框架中的控制器DispatchAction,Struts是Java的SSH三大web开发框架之一,需要的朋友可以参考下
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...
14. 简述synchronized和java.util.concurrent.locks.Lock的异同 ? 11 15. 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 11 16. abstract class和interface有什么区别? 12...
import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionForward;import org.apache.struts.action.ActionMapping;import org.apache.struts.actions.DispatchAction等缺少
import org.apache.struts.actions.DispatchAction; import com.sys.four.dao.service.FdcNoService; import com.sys.four.dao.service.FdiTorihikisakiService; import com.sys.four.dao.service.FdlCodeSevice; ...
这是个SSH整合的简单例子,Action是继承自DispatchAction,多个JSP页面或是form可以跳转到这一个Action中调用同一个或是不同滴方法,有兴趣滴可以看一下,绝对无误!
17.5.3、DispatchAction 17.6、验证框架 附录A:实用工具 18.1、JavaMail 18.1.1、James邮件服务器的下载及配置 18.1.2、JavaMail简介及配置 18.1.3、发送普通邮件 18.1.4、发送带附件的HTML风格邮件 ...
17.5.3、DispatchAction 17.6、验证框架 附录A:实用工具 18.1、JavaMail 18.1.1、James邮件服务器的下载及配置 18.1.2、JavaMail简介及配置 18.1.3、发送普通邮件 18.1.4、发送带附件的HTML风格邮件 ...
最近自学java中的框架-struts写了一些小例子,这都是很经典的程序,如果大家瞧得起要下载去看看,顺便给俺找找不足的地方。我的qq 821865130 email qingtian_hechen@163.com 希望大家能多多给我帮助。在此谢谢各位!...
4.12. dispatchAction是用什么技术实现的? 13 4.13. struts2.0的mvc模式?与struts1.0的区别? 13 4.14. struts的处理流程。 13 4.15. Struts/webwork 的工作机制,它有哪些标签 18 3 Spring部分 18 4.1. spring工作...
17.5.3、DispatchAction 17.6、验证框架 附录A:实用工具 18.1、JavaMail 18.1.1、James邮件服务器的下载及配置 18.1.2、JavaMail简介及配置 18.1.3、发送普通邮件 18.1.4、发送带附件的HTML风格邮件 18.2、...
客户端请求被ActionServlet接收,然后... 请求转交给Action或者DispatchAction,然后由Action或者DispatchAction调用模 型处理当前用户的请求,最后处理的结果再由ActionServlet调用JSP将处理结果回 复给客户端。
17.5.3、DispatchAction 17.6、验证框架 附录A:实用工具 18.1、JavaMail 18.1.1、James邮件服务器的下载及配置 18.1.2、JavaMail简介及配置 18.1.3、发送普通邮件 18.1.4、发送带附件的HTML风格邮件 ...
17.5.3、DispatchAction 17.6、验证框架 附录A:实用工具 18.1、JavaMail 18.1.1、James邮件服务器的下载及配置 18.1.2、JavaMail简介及配置 18.1.3、发送普通邮件 18.1.4、发送带附件的HTML风格邮件 ...
数据表Blob字段在Hibernate持久化映射文件中的type为org.springframework.orm.hibernate3.support.BlobByteArrayType,即Spring所提供的用户自定义的类型,而非java.sql.Blob。 3在Spring中使用org.springframework...
17.5.3、DispatchAction 17.6、验证框架 附录A:实用工具 18.1、JavaMail 18.1.1、James邮件服务器的下载及配置 18.1.2、JavaMail简介及配置 18.1.3、发送普通邮件 18.1.4、发送带附件的HTML风格邮件 18.2、...
17.5.3、DispatchAction 17.6、验证框架 附录A:实用工具 18.1、JavaMail 18.1.1、James邮件服务器的下载及配置 18.1.2、JavaMail简介及配置 18.1.3、发送普通邮件 18.1.4、发送带附件的HTML风格邮件 18.2、...