⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prototypecontroller.java

📁 anewssystem新闻发布系统集成使用了spring hibernate freemarker EXTJS等开源框架 可以作为学习参考
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package anni.core.web.prototype;


/*
 * Copyright 2002-2006 the original author or authors.
 *
 * 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.
 */
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.BeanUtils;

import org.springframework.util.Assert;

import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import org.springframework.web.servlet.mvc.LastModified;
import org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver;
import org.springframework.web.servlet.mvc.multiaction.MethodNameResolver;
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;
import org.springframework.web.util.NestedServletException;


/**
 * Controller implementation that allows multiple request types to be
 * handled by the same class. Subclasses of this class can handle several
 * different types of request with methods of the form
 *
 * <pre>
 * (ModelAndView | Map | void) actionName(HttpServletRequest request, HttpServletResponse response);</pre>
 *
 * May take a third parameter HttpSession in which an existing session will be required,
 * or a third parameter of an arbitrary class that gets treated as command
 * (i.e. an instance of the class gets created, and request parameters get bound to it)
 *
 * <p>These methods can throw any kind of exception, but should only let propagate
 * those that they consider fatal, or which their class or superclass is prepared to
 * catch by implementing an exception handler.
 *
 * <p>When returning just a {@link Map} instance view name translation will be used to generate
 * the view name. The configured {@link org.springframework.web.servlet.RequestToViewNameTranslator}
 * will be used to determine the view name.
 *
 * <p>When returning <code>void</code> a return value of <code>null</code> is assumed
 * meaning that the handler method is responsible for writing the response directly to
 * the supplied {@link HttpServletResponse}.
 *
 * <p>This model allows for rapid coding, but loses the advantage of compile-time
 * checking. It is similar to a Struts 1.1 DispatchAction, but more sophisticated.
 * Also supports delegation to another object.
 *
 * <p>An implementation of the MethodNameResolver interface defined in this package
 * should return a method name for a given request, based on any aspect of the request,
 * such as its URL or an "action" parameter. The actual strategy can be configured
 * via the "methodNameResolver" bean property, for each MultiActionController.
 *
 * <p>The default MethodNameResolver is InternalPathMethodNameResolver; further included
 * strategies are PropertiesMethodNameResolver and ParameterMethodNameResolver.
 *
 * <p>Subclasses can implement custom exception handler methods with names such as:
 *
 * <pre>
 * ModelAndView anyMeaningfulName(HttpServletRequest request, HttpServletResponse response, ExceptionClass exception);
 * </pre>
 *
 * The third parameter can be any subclass or Exception or RuntimeException.
 *
 * <p>There can also be an optional lastModified method for handlers, of signature:
 *
 * <pre>
 * long anyMeaningfulNameLastModified(HttpServletRequest request)</pre>
 *
 * If such a method is present, it will be invoked. Default return from getLastModified
 * is -1, meaning that the content must always be regenerated.
 *
 * <p>Note that method overloading isn't allowed.
 *
 * <p>See also the description of the workflow performed by
 * {@link AbstractController the superclass} (in that section of the class
 * level Javadoc entitled 'workflow').
 *
 * <p><b>Note:</b> For maximum data binding flexibility, consider direct usage
 * of a ServletRequestDataBinder in your controller method, instead of relying
 * on a declared command argument. This allows for full control over the entire
 * binder setup and usage, including the invocation of Validators and the
 * subsequent evaluation of binding/validation errors.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @author Colin Sampaleanu
 * @author Rob Harrop
 * @author Lingo
 * @since 2007-04-07
 * @see org.springframework.web.servlet.mvc.multiaction.MethodNameResolver
 * @see org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver
 * @see org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver
 * @see org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver
 * @see org.springframework.web.servlet.mvc.LastModified#getLastModified
 * @see org.springframework.web.bind.ServletRequestDataBinder
 */
public class PrototypeController extends AbstractController
    implements LastModified {
    /**
     * logger.
     */
    private static Log logger = LogFactory.getLog(PrototypeController.class);

    /** Suffix for last-modified methods. */
    public static final String LAST_MODIFIED_METHOD_SUFFIX = "LastModified";

    /** Default command name used for binding command objects: "command". */
    public static final String DEFAULT_COMMAND_NAME = "command";

    /** Log category to use when no mapped handler is found for a request. */
    public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web.servlet.PageNotFound";

    /** Additional logger to use when no mapped handler is found for a request. */
    private static Log pageNotFoundLogger = LogFactory.getLog(PAGE_NOT_FOUND_LOG_CATEGORY);

    /**
     * 请求.
     */
    protected HttpServletRequest request;

    /**
     * 响应.
     */
    protected HttpServletResponse response;

    /**
     * 会话.
     */
    protected HttpSession session;

    /**
     * ServletContext.
     */
    protected ServletContext context;

    /**
     * ModelAndView.
     */
    protected ModelAndView mv;

    /**
     * Helper object that knows how to return method names from incoming requests.
     * Can be overridden via the methodNameResolver bean property.
     */
    protected MethodNameResolver methodNameResolver = new InternalPathMethodNameResolver();

    /** List of Validators to apply to commands. */
    private Validator[] validators;

    /** Object we'll invoke methods on. Defaults to this. */
    private Object delegate;

    /** Methods, keyed by name. */
    private Map handlerMethodMap = new HashMap();

    /** LastModified methods, keyed by handler method name (without LAST_MODIFIED_SUFFIX). */
    private Map lastModifiedMethodMap = new HashMap();

    /** Methods, keyed by exception class. */
    private Map exceptionHandlerMap = new HashMap();

    /**
     * Constructor for MultiActionController that looks for handler methods
     * in the present subclass. Caches methods for quick invocation later.
     * This class's use of reflection will impose little overhead at runtime.
     */
    public PrototypeController() {
        this.delegate = this;
        registerHandlerMethods(this.delegate);

        // We'll accept no handler methods found here - a delegate might be set later on.
    }

    /**
     * Constructor for MultiActionController that looks for handler methods in delegate,
     * rather than a subclass of this class. Caches methods for quick invocation later.
     * @param delegateIn handler object. This doesn't need to implement any particular
     * interface, as everything is done using reflection.
     */
    public PrototypeController(Object delegateIn) {
        setDelegate(delegateIn);
    }

    /**
     * @see org.springframework.web.servlet.mvc.multiaction.MultiActionController#handleRequestInternal(HttpServletRequest,HttpServletResponse).
     * @param requestIn request
     * @param responseIn respnonseIn
     * @return ModelAndView mv
     * @throws Exception 异常
     */
    @Override
    protected ModelAndView handleRequestInternal(
        HttpServletRequest requestIn, HttpServletResponse responseIn)
        throws Exception {
        request = requestIn;
        response = responseIn;
        session = request.getSession();
        context = session.getServletContext();
        mv = new ModelAndView();

        try {
            String methodName = this.methodNameResolver
                .getHandlerMethodName(request);
            invokeNamedMethod(methodName);

            return mv;
        } catch (NoSuchRequestHandlingMethodException ex) {
            return handleNoSuchRequestHandlingMethod(ex, request, response);
        }
    }

    /**
     * Invokes the named method.
     * <p>Uses a custom exception handler if possible; otherwise, throw an
     * unchecked exception; wrap a checked exception or Throwable.
     *
     * @param methodName 方法名
     * @throws Exception 异常
     */
    protected final void invokeNamedMethod(String methodName)
        throws Exception {
        Method method = (Method) this.handlerMethodMap.get(methodName);

        if (method == null) {
            throw new NoSuchRequestHandlingMethodException(methodName,
                getClass());
        }

        try {
            method.invoke(this.delegate, new Object[0]);
        } catch (InvocationTargetException ex) {
            logger.error("error occur when invoke : " + method,
                ex.getCause());
            // The handler method threw an exception.
            this.mv = handleException(request, response,
                    ex.getTargetException());
        } catch (Exception ex) {
            logger.error("other exception : ", ex);
            // The binding process threw an exception.
            this.mv = handleException(request, response, ex);
        }
    }

    /**
     * Set the method name resolver that this class should use.
     * Allows parameterization of handler method mappings.
     *
     * @param methodNameResolverIn 方法名处理器
     */
    public final void setMethodNameResolver(
        MethodNameResolver methodNameResolverIn) {
        this.methodNameResolver = methodNameResolverIn;
    }

    /**
     * Return the MethodNameResolver used by this class.
     *
     * @return MethodNameResovler 方法名处理器
     */
    public final MethodNameResolver getMethodNameResolver() {
        return this.methodNameResolver;
    }

    /**
     * Set the Validators for this controller.
     * The Validator must support the specified command class.
     *
     * @param validatorsIn Validator
     */
    public final void setValidators(Validator[] validatorsIn) {
        this.validators = validatorsIn;
    }

    /**
     * Return the Validators for this controller.
     *
     * @return Validator[] 校验器
     */
    public final Validator[] getValidators() {
        return validators;
    }

    /**
     * Set the delegate used by this class. The default is <code>this</code>,
     * assuming that handler methods have been added by a subclass.
     * <p>This method does not get invoked once the class is configured.
     * @param delegateIn an object containing handler methods
     */
    public final void setDelegate(Object delegateIn) {
        Assert.notNull(delegateIn, "Delegate must not be null");
        this.delegate = delegateIn;
        registerHandlerMethods(this.delegate);

        // There must be SOME handler methods.
        if (this.handlerMethodMap.isEmpty()) {
            throw new IllegalStateException(
                "No handler methods in class [" + this.delegate.getClass()
                + "]");
        }
    }

    /**
     * Registers all handlers methods on the delegate object.
     *
     * @param delegateIn delegate
     */
    private void registerHandlerMethods(Object delegateIn) {
        this.handlerMethodMap.clear();
        this.lastModifiedMethodMap.clear();
        this.exceptionHandlerMap.clear();

        // Look at all methods in the subclass, trying to find
        // methods that are validators according to our criteria
        Method[] methods = delegateIn.getClass().getMethods();

        for (int i = 0; i < methods.length; i++) {
            // We're looking for methods with given parameters.
            Method method = methods[i];

            if (isHandlerMethod(method)) {
                registerHandlerMethod(method);
                registerLastModifiedMethodIfExists(delegateIn, method);
            }
        }

        // Now look for exception handlers.
        for (int i = 0; i < methods.length; i++) {
            Method method = methods[i];

            if (isExceptionHandlerMethod(method)) {
                // Have an exception handler
                registerExceptionHandlerMethod(method);
            }
        }
    }

    /**
     * Is the supplied method a valid handler method?
     * <p>Does not consider <code>Controller.handleRequest</code> itself
     * as handler method (to avoid potential stack overflow).
     *
     * @param method 方法
     * @return boolean 是否是handler方法
     */
    private boolean isHandlerMethod(Method method) {
        Class returnType = method.getReturnType();

        if (void.class.equals(returnType)) {
            Class[] parameterTypes = method.getParameterTypes();

            return ((parameterTypes.length == 0)
            || (parameterTypes.length == 3));
        }

        return false;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -