Apache struts-1.3.10 a stable version

源代码在线查看: exceptionhandler.java

软件大小: 45451 K
上传用户: moxcki
关键词: version Apache struts stable
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*
				 * $Id: ExceptionHandler.java 471754 2006-11-06 14:55:09Z husted $
				 *
				 * Licensed to the Apache Software Foundation (ASF) under one
				 * or more contributor license agreements.  See the NOTICE file
				 * distributed with this work for additional information
				 * regarding copyright ownership.  The ASF licenses this file
				 * to you 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 org.apache.commons.logging.Log;
				import org.apache.commons.logging.LogFactory;
				import org.apache.struts.Globals;
				import org.apache.struts.config.ExceptionConfig;
				import org.apache.struts.util.MessageResources;
				import org.apache.struts.util.ModuleException;
				
				import javax.servlet.RequestDispatcher;
				import javax.servlet.ServletException;
				import javax.servlet.http.HttpServletRequest;
				import javax.servlet.http.HttpServletResponse;
				
				import java.io.IOException;
				
				/**
				 * An ExceptionHandler is configured in the Struts
				 * configuration file to handle a specific type of exception thrown by an
				 * Action.execute method.
				 *
				 * @since Struts 1.1
				 */
				public class ExceptionHandler {
				    /**
				     * The name of a configuration property which can be set to specify an
				     * alternative path which should be used when the HttpServletResponse has
				     * already been committed. To use this, in your
				     * struts-config.xml specify the exception handler like
				     * this:
				     * 
				     *   <exception
				     *       key="GlobalExceptionHandler.default"
				     *       type="java.lang.Exception"
				     *       path="/ErrorPage.jsp">
				     *       <set-property key="INCLUDE_PATH" value="/error.jsp" />
				     *   </exception>
				     *  
				     *  You would want to use this when your normal ExceptionHandler
				     * path is a Tiles definition or otherwise unsuitable for use in an
				     * include context.  If you do not use this, and you do not
				     * specify "SILENT_IF_COMMITTED" then the ExceptionHandler will attempt to
				     * forward to the same path which would be used in normal circumstances,
				     * specified using the "path" attribute in the <exception>
				     * element.
				     *
				     * @since Struts 1.3
				     */
				    public static final String INCLUDE_PATH = "INCLUDE_PATH";
				
				    /**
				     * The name of a configuration property which indicates that Struts
				     * should do nothing if the response has already been committed.  This
				     * suppresses the default behavior, which is to use an "include" rather
				     * than a "forward" in this case in hopes of providing some meaningful
				     * information to the browser. To use this, in your
				     * struts-config.xml specify the exception handler like
				     * this:
				     * 
				     *   <exception
				     *       key="GlobalExceptionHandler.default"
				     *       type="java.lang.Exception"
				     *       path="/ErrorPage.jsp">
				     *       <set-property key="SILENT_IF_COMMITTED" value="true" />
				     *   </exception>
				     *  
				     * To be effective, this value must be defined to the literal String
				     * "true". If it is not defined or defined to any other value, the default
				     * behavior will be used.  You only need to use this if you do not
				     * want error information displayed in the browser when Struts intercepts
				     * an exception after the response has been committed.
				     *
				     * @since Struts 1.3
				     */
				    public static final String SILENT_IF_COMMITTED = "SILENT_IF_COMMITTED";
				
				    /**
				     * Commons logging instance.
				     */
				    private static final Log LOG = LogFactory.getLog(ExceptionHandler.class);
				
				    /**
				     * The message resources for this package.
				     */
				    private static MessageResources messages =
				        MessageResources.getMessageResources(
				            "org.apache.struts.action.LocalStrings");
				
				    /**
				     *  Handle the Exception. Return the ActionForward instance (if any)
				     * returned by the called ExceptionHandler. 
				     *
				     * @param ex           The exception to handle
				     * @param ae           The ExceptionConfig corresponding to the exception
				     * @param mapping      The ActionMapping we are processing
				     * @param formInstance The ActionForm we are processing
				     * @param request      The servlet request we are processing
				     * @param response     The servlet response we are creating
				     * @return The ActionForward instance (if any) returned by
				     *         the called ExceptionHandler.
				     * @throws ServletException if a servlet exception occurs
				     * @since Struts 1.1
				     */
				    public ActionForward execute(Exception ex, ExceptionConfig ae,
				        ActionMapping mapping, ActionForm formInstance,
				        HttpServletRequest request, HttpServletResponse response)
				        throws ServletException {
				        LOG.debug("ExceptionHandler executing for exception " + ex);
				
				        ActionForward forward;
				        ActionMessage error;
				        String property;
				
				        // Build the forward from the exception mapping if it exists
				        // or from the form input
				        if (ae.getPath() != null) {
				            forward = new ActionForward(ae.getPath());
				        } else {
				            forward = mapping.getInputForward();
				        }
				
				        // Figure out the error
				        if (ex instanceof ModuleException) {
				            error = ((ModuleException) ex).getActionMessage();
				            property = ((ModuleException) ex).getProperty();
				        } else {
				            error = new ActionMessage(ae.getKey(), ex.getMessage());
				            property = error.getKey();
				        }
				
				        this.logException(ex);
				
				        // Store the exception
				        request.setAttribute(Globals.EXCEPTION_KEY, ex);
				        this.storeException(request, property, error, forward, ae.getScope());
				
				        if (!response.isCommitted()) {
				            return forward;
				        }
				
				        LOG.debug("Response is already committed, so forwarding will not work."
				            + " Attempt alternate handling.");
				
				        if (!silent(ae)) {
				            handleCommittedResponse(ex, ae, mapping, formInstance, request,
				                response, forward);
				        } else {
				            LOG.warn("ExceptionHandler configured with " + SILENT_IF_COMMITTED
				                + " and response is committed.", ex);
				        }
				
				        return null;
				    }
				
				    /**
				     * Attempt to give good information when the response has already been
				     * committed when the exception was thrown. This happens often when Tiles
				     * is used. Base implementation will see if the INCLUDE_PATH property has
				     * been set, or if not, it will attempt to use the same path to which
				     * control would have been forwarded.
				     *
				     * @param ex            The exception to handle
				     * @param config        The ExceptionConfig we are processing
				     * @param mapping       The ActionMapping we are processing
				     * @param formInstance  The ActionForm we are processing
				     * @param request       The servlet request we are processing
				     * @param response      The servlet response we are creating
				     * @param actionForward The ActionForward we are processing
				     * @since Struts 1.3
				     */
				    protected void handleCommittedResponse(Exception ex,
				        ExceptionConfig config, ActionMapping mapping, ActionForm formInstance,
				        HttpServletRequest request, HttpServletResponse response,
				        ActionForward actionForward) {
				        String includePath = determineIncludePath(config, actionForward);
				
				        if (includePath != null) {
				            if (includePath.startsWith("/")) {
				                LOG.debug("response committed, "
				                    + "but attempt to include results "
				                    + "of actionForward path");
				
				                RequestDispatcher requestDispatcher =
				                    request.getRequestDispatcher(includePath);
				
				                try {
				                    requestDispatcher.include(request, response);
				
				                    return;
				                } catch (IOException e) {
				                    LOG.error("IOException when trying to include "
				                        + "the error page path " + includePath, e);
				                } catch (ServletException e) {
				                    LOG.error("ServletException when trying to include "
				                        + "the error page path " + includePath, e);
				                }
				            } else {
				                LOG.warn("Suspicious includePath doesn't seem likely to work, "
				                    + "so skipping it: " + includePath
				                    + "; expected path to start with '/'");
				            }
				        }
				
				        LOG.debug("Include not available or failed; "
				            + "try writing to the response directly.");
				
				        try {
				            response.getWriter().println("Unexpected error: " + ex);
				            response.getWriter().println("				            ex.printStackTrace(response.getWriter());
				            response.getWriter().println("-->");
				        } catch (IOException e) {
				            LOG.error("Error giving minimal information about exception", e);
				            LOG.error("Original exception: ", ex);
				        }
				    }
				
				    /**
				     * Return a path to which an include should be attempted in the case
				     * when the response was committed before the ExceptionHandler
				     * was invoked.   If the ExceptionConfig has the
				     * property INCLUDE_PATH defined, then the value of that
				     * property will be returned. Otherwise, the ActionForward path is
				     * returned. 
				     *
				     * @param config        Configuration element
				     * @param actionForward Forward to use on error
				     * @return Path of resource to include
				     * @since Struts 1.3
				     */
				    protected String determineIncludePath(ExceptionConfig config,
				        ActionForward actionForward) {
				        String includePath = config.getProperty("INCLUDE_PATH");
				
				        if (includePath == null) {
				            includePath = actionForward.getPath();
				        }
				
				        return includePath;
				    }
				
				    /**
				     * Logs the Exception using commons-logging.
				     *
				     * @param e The Exception to LOG.
				     * @since Struts 1.2
				     */
				    protected void logException(Exception e) {
				        LOG.debug(messages.getMessage("exception.LOG"), e);
				    }
				
				    /**
				     * Default implementation for handling an ActionMessage
				     * generated from an Exception during Action
				     * delegation. The default implementation is to set an attribute of the
				     * request or session, as defined by the scope provided (the scope from
				     * the exception mapping). An ActionMessages instance is
				     * created, the error is added to the collection and the collection is set
				     * under the Globals.ERROR_KEY.
				     *
				     * @param request  The request we are handling
				     * @param property The property name to use for this error
				     * @param error    The error generated from the exception mapping
				     * @param forward  The forward generated from the input path (from the
				     *                 form or exception mapping)
				     * @param scope    The scope of the exception mapping.
				     * @since Struts 1.2
				     */
				    protected void storeException(HttpServletRequest request, String property,
				        ActionMessage error, ActionForward forward, String scope) {
				        ActionMessages errors = new ActionMessages();
				
				        errors.add(property, error);
				
				        if ("request".equals(scope)) {
				            request.setAttribute(Globals.ERROR_KEY, errors);
				        } else {
				            request.getSession().setAttribute(Globals.ERROR_KEY, errors);
				        }
				    }
				
				    /**
				     * Indicate whether this Handler has been configured to be silent.  In
				     * the base implementation, this is done by specifying the value
				     * "true" for the property "SILENT_IF_COMMITTED" in the
				     * ExceptionConfig.
				     *
				     * @param config The ExceptionConfiguration we are handling
				     * @return True if Handler is silent
				     * @since Struts 1.3
				     */
				    private boolean silent(ExceptionConfig config) {
				        return "true".equals(config.getProperty(SILENT_IF_COMMITTED));
				    }
				}
							

相关资源