?? actionservlet.java
字號(hào):
/*
* $Id: ActionServlet.java 264684 2005-08-30 03:08:01Z niallp $
*
* Copyright 2000-2005 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.action;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.MissingResourceException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.converters.BigDecimalConverter;
import org.apache.commons.beanutils.converters.BigIntegerConverter;
import org.apache.commons.beanutils.converters.BooleanConverter;
import org.apache.commons.beanutils.converters.ByteConverter;
import org.apache.commons.beanutils.converters.CharacterConverter;
import org.apache.commons.beanutils.converters.DoubleConverter;
import org.apache.commons.beanutils.converters.FloatConverter;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.beanutils.converters.LongConverter;
import org.apache.commons.beanutils.converters.ShortConverter;
import org.apache.commons.collections.FastHashMap;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.RuleSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.Globals;
import org.apache.struts.config.ConfigRuleSet;
import org.apache.struts.config.DataSourceConfig;
import org.apache.struts.config.FormBeanConfig;
import org.apache.struts.config.MessageResourcesConfig;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.config.ModuleConfigFactory;
import org.apache.struts.config.PlugInConfig;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.MessageResourcesFactory;
import org.apache.struts.util.ModuleUtils;
import org.apache.struts.util.RequestUtils;
import org.apache.struts.util.ServletContextWriter;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* <p><strong>ActionServlet</strong> provides the "controller" in the
* Model-View-Controller (MVC) design pattern for web applications that is
* commonly known as "Model 2". This nomenclature originated with a
* description in the JavaServerPages Specification, version 0.92, and has
* persisted ever since (in the absence of a better name).</p>
*
* <p>Generally, a "Model 2" application is architected as follows:</p>
* <ul>
* <li>The user interface will generally be created with server pages, which
* will not themselves contain any business logic. These pages represent
* the "view" component of an MVC architecture.</li>
* <li>Forms and hyperlinks in the user interface that require business logic
* to be executed will be submitted to a request URI that is mapped to this
* servlet.</li>
* <li>There can be <b>one</b> instance of this servlet class,
* which receives and processes all requests that change the state of
* a user's interaction with the application. The servlet delegates the
* handling of a request to a {@link RequestProcessor} object. This component
* represents the "controller" component of an MVC architecture.</li>
* <li>The <code>RequestProcessor</code> selects and invokes an {@link Action} class to perform
* the requested business logic, or delegates the response to another resource.</li>
* <li>The <code>Action</code> classes can manipulate the state of the application's
* interaction with the user, typically by creating or modifying JavaBeans
* that are stored as request or session attributes (depending on how long
* they need to be available). Such JavaBeans represent the "model"
* component of an MVC architecture.</li>
* <li>Instead of producing the next page of the user interface directly,
* <code>Action</code> classes generally return an {@link ActionForward} to indicate
* which resource should handle the response. If the <code>Action</code>
* does not return null, the <code>RequestProcessor</code> forwards or
* redirects to the specified resource (by utilizing
* <code>RequestDispatcher.forward</code> or <code>Response.sendRedirect</code>)
* so as to produce the next page of the user interface.</li>
* </ul>
*
* <p>The standard version of <code>RequestsProcessor</code> implements the
* following logic for each incoming HTTP request. You can override
* some or all of this functionality by subclassing this object and
* implementing your own version of the processing.</p>
* <ul>
* <li>Identify, from the incoming request URI, the substring that will be
* used to select an action procedure.</li>
* <li>Use this substring to map to the Java class name of the corresponding
* action class (an implementation of the <code>Action</code> interface).
* </li>
* <li>If this is the first request for a particular <code>Action</code> class,
* instantiate an instance of that class and cache it for future use.</li>
* <li>Optionally populate the properties of an <code>ActionForm</code> bean
* associated with this mapping.</li>
* <li>Call the <code>execute</code> method of this <code>Action</code> class, passing
* on a reference to the mapping that was used, the relevant form-bean
* (if any), and the request and the response that were passed to the
* controller by the servlet container (thereby providing access to any
* specialized properties of the mapping itself as well as to the
* ServletContext).
* </li>
* </ul>
*
* <p>The standard version of <code>ActionServlet</code> is configured based
* on the following servlet initialization parameters, which you will specify
* in the web application deployment descriptor (<code>/WEB-INF/web.xml</code>)
* for your application. Subclasses that specialize this servlet are free to
* define additional initialization parameters. </p>
* <ul>
* <li><strong>config</strong> - Comma-separated list of context-relative
* path(s) to the XML resource(s) containing the configuration information
* for the default module. (Multiple files support since Struts 1.1)
* [/WEB-INF/struts-config.xml].</li>
* <li><strong>config/${module}</strong> - Comma-separated list of
* Context-relative path(s) to the XML resource(s)
* containing the configuration information for the module that
* will use the specified prefix (/${module}). This can be repeated as many
* times as required for multiple modules. (Since Struts 1.1)</li>
* <li><strong>configFactory</strong> - The Java class name of the
* <code>ModuleConfigFactory</code> used to create the implementation of the
* <code>ModuleConfig</code> interface.
* [org.apache.struts.config.impl.DefaultModuleConfigFactory]
* </li>
* <li><strong>convertNull</strong> - Force simulation of the Struts 1.0 behavior
* when populating forms. If set to true, the numeric Java wrapper class types
* (like <code>java.lang.Integer</code>) will default to null (rather than 0).
* (Since Struts 1.1) [false] </li>
* <li><strong>rulesets</strong> - Comma-delimited list of fully qualified
* classnames of additional <code>org.apache.commons.digester.RuleSet</code>
* instances that should be added to the <code>Digester</code> that will
* be processing <code>struts-config.xml</code> files. By default, only
* the <code>RuleSet</code> for the standard configuration elements is
* loaded. (Since Struts 1.1)</li>
* <li><strong>validating</strong> - Should we use a validating XML parser to
* process the configuration file (strongly recommended)? [true]</li>
* </ul>
*
* @version $Rev: 264684 $ $Date: 2005-08-30 04:08:01 +0100 (Tue, 30 Aug 2005) $
*/
public class ActionServlet extends HttpServlet {
// ----------------------------------------------------- Instance Variables
/**
* <p>Comma-separated list of context-relative path(s) to our configuration
* resource(s) for the default module.</p>
*/
protected String config = "/WEB-INF/struts-config.xml";
/**
* <p>The Digester used to produce ModuleConfig objects from a
* Struts configuration file.</p>
*
* @since Struts 1.1
*/
protected Digester configDigester = null;
/**
* <p>The flag to request backwards-compatible conversions for form bean
* properties of the Java wrapper class types.</p>
*
* @since Struts 1.1
*/
protected boolean convertNull = false;
/**
* <p>The JDBC data sources that has been configured for this module,
* if any, keyed by the servlet context attribute under which they are
* stored.</p>
*/
protected FastHashMap dataSources = new FastHashMap();
/**
* <p>The resources object for our internal resources.</p>
*/
protected MessageResources internal = null;
/**
* <p>The Java base name of our internal resources.</p>
* @since Struts 1.1
*/
protected String internalName = "org.apache.struts.action.ActionResources";
/**
* <p>Commons Logging instance.</p>
*
* @since Struts 1.1
*/
protected static Log log = LogFactory.getLog(ActionServlet.class);
/**
* <p>The <code>RequestProcessor</code> instance we will use to process
* all incoming requests.</p>
*
* @since Struts 1.1
*/
protected RequestProcessor processor = null;
/**
* <p>The set of public identifiers, and corresponding resource names, for
* the versions of the configuration file DTDs that we know about. There
* <strong>MUST</strong> be an even number of Strings in this list!</p>
*/
protected String registrations[] = {
"-//Apache Software Foundation//DTD Struts Configuration 1.0//EN",
"/org/apache/struts/resources/struts-config_1_0.dtd",
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN",
"/org/apache/struts/resources/struts-config_1_1.dtd",
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN",
"/org/apache/struts/resources/struts-config_1_2.dtd",
"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",
"/org/apache/struts/resources/web-app_2_2.dtd",
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",
"/org/apache/struts/resources/web-app_2_3.dtd"
};
/**
* <p>The URL pattern to which we are mapped in our web application
* deployment descriptor.</p>
*/
protected String servletMapping = null; // :FIXME: - multiples?
/**
* <p>The servlet name under which we are registered in our web application
* deployment descriptor.</p>
*/
protected String servletName = null;
// ---------------------------------------------------- HttpServlet Methods
/**
* <p>Gracefully shut down this controller servlet, releasing any resources
* that were allocated at initialization.</p>
*/
public void destroy() {
if (log.isDebugEnabled()) {
log.debug(internal.getMessage("finalizing"));
}
destroyModules();
destroyInternal();
getServletContext().removeAttribute(Globals.ACTION_SERVLET_KEY);
// Release our LogFactory and Log instances (if any)
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
classLoader = ActionServlet.class.getClassLoader();
}
try {
LogFactory.release(classLoader);
} catch (Throwable t) {
; // Servlet container doesn't have the latest version
; // of commons-logging-api.jar installed
// :FIXME: Why is this dependent on the container's version of commons-logging?
// Shouldn't this depend on the version packaged with Struts?
/*
Reason: LogFactory.release(classLoader); was added as
an attempt to investigate the OutOfMemory error reported on Bugzilla #14042.
It was committed for version 1.136 by craigmcc
*/
}
PropertyUtils.clearDescriptors();
}
/**
* <p>Initialize this servlet. Most of the processing has been factored into
* support methods so that you can override particular functionality at a
* fairly granular level.</p>
*
* @exception ServletException if we cannot configure ourselves correctly
*/
public void init() throws ServletException {
// Wraps the entire initialization in a try/catch to better handle
// unexpected exceptions and errors to provide better feedback
// to the developer
try {
initInternal();
initOther();
initServlet();
getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);
initModuleConfigFactory();
// Initialize modules as needed
ModuleConfig moduleConfig = initModuleConfig("", config);
initModuleMessageResources(moduleConfig);
initModuleDataSources(moduleConfig);
initModulePlugIns(moduleConfig);
moduleConfig.freeze();
Enumeration names = getServletConfig().getInitParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
if (!name.startsWith("config/")) {
continue;
}
String prefix = name.substring(6);
moduleConfig = initModuleConfig
(prefix, getServletConfig().getInitParameter(name));
initModuleMessageResources(moduleConfig);
initModuleDataSources(moduleConfig);
initModulePlugIns(moduleConfig);
moduleConfig.freeze();
}
this.initModulePrefixes(this.getServletContext());
this.destroyConfigDigester();
} catch (UnavailableException ex) {
throw ex;
} catch (Throwable t) {
// The follow error message is not retrieved from internal message
// resources as they may not have been able to have been
// initialized
log.error("Unable to initialize Struts ActionServlet due to an "
+ "unexpected exception or error thrown, so marking the "
+ "servlet as unavailable. Most likely, this is due to an "
+ "incorrect or missing library dependency.", t);
throw new UnavailableException(t.getMessage());
}
}
/**
* <p>Saves a String[] of module prefixes in the ServletContext under
* Globals.MODULE_PREFIXES_KEY. <strong>NOTE</strong> -
* the "" prefix for the default module is not included in this list.</p>
*
* @param context The servlet context.
* @since Struts 1.2
*/
protected void initModulePrefixes(ServletContext context) {
ArrayList prefixList = new ArrayList();
Enumeration names = context.getAttributeNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
if (!name.startsWith(Globals.MODULE_KEY)) {
continue;
}
String prefix = name.substring(Globals.MODULE_KEY.length());
if (prefix.length() > 0) {
prefixList.add(prefix);
}
}
String[] prefixes = (String[]) prefixList.toArray(new String[prefixList.size()]);
context.setAttribute(Globals.MODULE_PREFIXES_KEY, prefixes);
}
/**
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -