struts2常見的result類型的用法

這個是官方文檔的上面對result類型的描述

我自己又找了一箇中文的:

本文重點分享一下幾個常用的result類型之後的原理:

一:dispatcher

從源碼分析:

public void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Forwarding to location " + finalLocation);
        }

        PageContext pageContext = ServletActionContext.getPageContext();

        if (pageContext != null) {
            pageContext.include(finalLocation);
        } else {
            HttpServletRequest request = ServletActionContext.getRequest();
            HttpServletResponse response = ServletActionContext.getResponse();
            RequestDispatcher dispatcher = request.getRequestDispatcher(finalLocation);

            //add parameters passed on the location to #parameters
            // see WW-2120
            if (StringUtils.isNotEmpty(finalLocation) && finalLocation.indexOf("?") > 0) {
                String queryString = finalLocation.substring(finalLocation.indexOf("?") + 1);
                Map<String, Object> parameters = getParameters(invocation);
                Map<String, Object> queryParams = urlHelper.parseQueryString(queryString, true);
                if (queryParams != null && !queryParams.isEmpty())
                    parameters.putAll(queryParams);
            }

            // if the view doesn't exist, let's do a 404
            if (dispatcher == null) {
                response.sendError(404, "result '" + finalLocation + "' not found");
                return;
            }

            //if we are inside an action tag, we always need to do an include
            Boolean insideActionTag = (Boolean) ObjectUtils.defaultIfNull(request.getAttribute(StrutsStatics.STRUTS_ACTION_TAG_INVOCATION), Boolean.FALSE);

            // If we're included, then include the view
            // Otherwise do forward
            // This allow the page to, for example, set content type
            if (!insideActionTag && !response.isCommitted() && (request.getAttribute("javax.servlet.include.servlet_path") == null)) {
                request.setAttribute("struts.view_uri", finalLocation);
                request.setAttribute("struts.request_uri", request.getRequestURI());

                dispatcher.forward(request, response);
            } else {
                dispatcher.include(request, response);
            }
        }
    }

結果又三個方向:

pageContext.include(finalLocation);

dispatcher.forward(request, response); 

dispatcher.include(request, response);

而forward和include是差不多的。

 

二:chain

主要用於把相關的幾個action連接起來,共同完成一個功能

public void execute(ActionInvocation invocation) throws Exception {
        // if the finalNamespace wasn't explicitly defined, assume the current one
        if (this.namespace == null) {
            this.namespace = invocation.getProxy().getNamespace();
        }

        ValueStack stack = ActionContext.getContext().getValueStack();
        String finalNamespace = TextParseUtil.translateVariables(namespace, stack);
        String finalActionName = TextParseUtil.translateVariables(actionName, stack);
        String finalMethodName = this.methodName != null
                ? TextParseUtil.translateVariables(this.methodName, stack)
                : null;

        if (isInChainHistory(finalNamespace, finalActionName, finalMethodName)) {
            addToHistory(finalNamespace, finalActionName, finalMethodName);
            throw new XWorkException("Infinite recursion detected: "
                    + ActionChainResult.getChainHistory().toString());
        }

        if (ActionChainResult.getChainHistory().isEmpty() && invocation != null && invocation.getProxy() != null) {
            addToHistory(finalNamespace, invocation.getProxy().getActionName(), invocation.getProxy().getMethod());
        }
        addToHistory(finalNamespace, finalActionName, finalMethodName);

        HashMap<String, Object> extraContext = new HashMap<String, Object>();
        extraContext.put(ActionContext.VALUE_STACK, ActionContext.getContext().getValueStack());
        extraContext.put(ActionContext.PARAMETERS, ActionContext.getContext().getParameters());
        extraContext.put(CHAIN_HISTORY, ActionChainResult.getChainHistory());

        if (LOG.isDebugEnabled()) {
            LOG.debug("Chaining to action " + finalActionName);
        }

        proxy = actionProxyFactory.createActionProxy(finalNamespace, finalActionName, finalMethodName, extraContext);
        proxy.execute();
    }

原理是根據action所在的namespace,action,method創建一個proxy代理,並且執行代理的過程。由於是在多個Action之間在同一個http請求中傳遞,所以可以共享其中的資源,這就是上面history的意思。根據以前context中的內容,共享給下面action.

三:redirect和redirection

由於都是一個類ServletRedirectResult中的方法,所以可以當做一個來考慮。

protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
        ActionContext ctx = invocation.getInvocationContext();
        HttpServletRequest request = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
        HttpServletResponse response = (HttpServletResponse) ctx.get(ServletActionContext.HTTP_RESPONSE);

        if (isPathUrl(finalLocation)) {
            if (!finalLocation.startsWith("/")) {
                ActionMapping mapping = actionMapper.getMapping(request, Dispatcher.getInstance().getConfigurationManager());
                String namespace = null;
                if (mapping != null) {
                    namespace = mapping.getNamespace();
                }

                if ((namespace != null) && (namespace.length() > 0) && (!"/".equals(namespace))) {
                    finalLocation = namespace + "/" + finalLocation;
                } else {
                    finalLocation = "/" + finalLocation;
                }
            }

            // if the URL's are relative to the servlet context, append the servlet context path
            if (prependServletContext && (request.getContextPath() != null) && (request.getContextPath().length() > 0)) {
                finalLocation = request.getContextPath() + finalLocation;
            }

            ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(invocation.getResultCode());
            if (resultConfig != null) {
                Map<String, String> resultConfigParams = resultConfig.getParams();

                for (Map.Entry<String, String> e : resultConfigParams.entrySet()) {
                    if (!getProhibitedResultParams().contains(e.getKey())) {
                        String potentialValue = e.getValue() == null ? "" : conditionalParse(e.getValue(), invocation);
                        if (!suppressEmptyParameters || ((potentialValue != null) && (potentialValue.length() > 0))) {
                            requestParameters.put(e.getKey(), potentialValue);
                        }
                    }
                }
            }

            StringBuilder tmpLocation = new StringBuilder(finalLocation);
            urlHelper.buildParametersString(requestParameters, tmpLocation, "&");

            // add the anchor
            if (anchor != null) {
                tmpLocation.append('#').append(anchor);
            }

            finalLocation = response.encodeRedirectURL(tmpLocation.toString());
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("Redirecting to finalLocation " + finalLocation);
        }

        sendRedirect(response, finalLocation);
    }

方法的結果都是使用這個方法作爲跳轉:sendRedirect(response, finalLocation);重定向。

其他的velocity,freemarker,是整合了模板引擎,這個以前我竟然不知道,google了一下,發現還是很簡單的。大家可以試着加到struts裏面。




 


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章