Source Taste: Struts 2 org.apache.struts2.dispatcher.Dispatcher

来源:互联网 发布:c专家编程电子书 编辑:程序博客网 时间:2024/06/02 07:34

PART 1:

/** * A utility class the actual dispatcher delegates most of its tasks to. Each instance * of the primary dispatcher holds an instance of this dispatcher to be shared for * all requests. * * @see org.apache.struts2.dispatcher.FilterDispatcher */public class Dispatcher {    /**     * Provide a logging instance.     */    private static final Logger LOG = LoggerFactory.getLogger(Dispatcher.class);    /**     * Provide a thread local instance.     */    private static ThreadLocal<Dispatcher> instance = new ThreadLocal<Dispatcher>();    /**     * Store list of DispatcherListeners.     */    private static List<DispatcherListener> dispatcherListeners =        new CopyOnWriteArrayList<DispatcherListener>();

Notice that

1. the ThreadLocal and theCopyOnWriteArrayList, both for concurrency scenarios.

2. This is a util class, rather than an interface.


PART 2:

/**     * Create a context map containing all the wrapped request objects     *     * @param request The servlet request     * @param response The servlet response     * @param mapping The action mapping     * @param context The servlet context     * @return A map of context objects     */    public Map<String,Object> createContextMap(HttpServletRequest request, HttpServletResponse response,            ActionMapping mapping, ServletContext context) {        // request map wrapping the http request objects        Map requestMap = new RequestMap(request);        // parameters map wrapping the http parameters.  ActionMapping parameters are now handled and applied separately        Map params = new HashMap(request.getParameterMap());        // session map wrapping the http session        Map session = new SessionMap(request);        // application map wrapping the ServletContext        Map application = new ApplicationMap(context);        Map<String,Object> extraContext = createContextMap(requestMap, params, session, application, request, response, context);        if (mapping != null) {            extraContext.put(ServletActionContext.ACTION_MAPPING, mapping);        }        return extraContext;    }
Noteworthy:

1. RequestMap/SessionMap/ApplicationMap.

2. appliation map wrapping the ServletContext.


PART 3:

/**     * Load Action class for mapping and invoke the appropriate Action method, or go directly to the Result.     * <p/>     * This method first creates the action context from the given parameters,     * and then loads an <tt>ActionProxy</tt> from the given action name and namespace.     * After that, the Action method is executed and output channels through the response object.     * Actions not found are sent back to the user via the {@link Dispatcher#sendError} method,     * using the 404 return code.     * All other errors are reported by throwing a ServletException.     *     * @param request  the HttpServletRequest object     * @param response the HttpServletResponse object     * @param mapping  the action mapping object     * @throws ServletException when an unknown error occurs (not a 404, but typically something that     *                          would end up as a 5xx by the servlet container)     * @param context Our ServletContext object     */    public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,                              ActionMapping mapping) throws ServletException {        Map<String, Object> extraContext = createContextMap(request, response, mapping, context);        // If there was a previous value stack, then create a new copy and pass it in to be used by the new Action        ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);        boolean nullStack = stack == null;        if (nullStack) {            ActionContext ctx = ActionContext.getContext();            if (ctx != null) {                stack = ctx.getValueStack();            }        }        if (stack != null) {            extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack));        }        String timerKey = "Handling request from Dispatcher";        try {            UtilTimerStack.push(timerKey);            String namespace = mapping.getNamespace();            String name = mapping.getName();            String method = mapping.getMethod();            Configuration config = configurationManager.getConfiguration();            ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(                    namespace, name, method, extraContext, true, false);            request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());            // if the ActionMapping says to go straight to a result, do it!            if (mapping.getResult() != null) {                Result result = mapping.getResult();                result.execute(proxy.getInvocation());            } else {                proxy.execute();            }            // If there was a previous value stack then set it back onto the request            if (!nullStack) {                request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);            }        } catch (ConfigurationException e) {        // WW-2874 Only log error if in devMode            if (devMode) {                String reqStr = request.getRequestURI();                if (request.getQueryString() != null) {                    reqStr = reqStr + "?" + request.getQueryString();                }                LOG.error("Could not find action or result\n" + reqStr, e);            } else {                if (LOG.isWarnEnabled()) {                    LOG.warn("Could not find action or result", e);                }            }            sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);        } catch (Exception e) {            if (handleException || devMode) {                sendError(request, response, context, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);            } else {                throw new ServletException(e);            }        } finally {            UtilTimerStack.pop(timerKey);        }    }


原创粉丝点击