刨根問底-struts-返回結果result詳解

刨根問底-strtus-詳解加載struts.xml文件

分析了加載action標籤的具體方法,

刨根問底-struts-怎麼預加載配置的相應的信息

分析了加載action標籤的具體過程。

刨根問底-struts-serviceAction()建立並執行action

具體分析了建立action,而且執行action,返回結果result,如今在詳細的分析 result是怎麼執行的?請看流程圖: java


一、DefaultActionInvocation的invoke()執行了action,而且返回來resultCode,後面調用executeResult()執行結果 apache

回來再看看DefaultActionInvocation中executeResult()方法: ide

private void executeResult() throws Exception {
        result = createResult();

        String timerKey = "executeResult: " + getResultCode();
        try {
            UtilTimerStack.push(timerKey);
            if (result != null) {
                result.execute(this);
            } else if (resultCode != null && !Action.NONE.equals(resultCode)) {
                throw new ConfigurationException("No result defined for action " + getAction().getClass().getName()
                        + " and result " + getResultCode(), proxy.getConfig());
            } else {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("No result returned for action " + getAction().getClass().getName() + " at " + proxy.getConfig().getLocation());
                }
            }
        } finally {
            UtilTimerStack.pop(timerKey);
        }
    }
註釋:(1)result = createResult()建立result對象

(2)result.execute(this)執行這個方法 ui

二、createResult()方法: this

public Result createResult() throws Exception {

        if (explicitResult != null) {
            Result ret = explicitResult;
            explicitResult = null;

            return ret;
        }
        ActionConfig config = proxy.getConfig();
        Map<String, ResultConfig> results = config.getResults();

        ResultConfig resultConfig = null;

        synchronized (config) {
            try {
                resultConfig = results.get(resultCode);
            } catch (NullPointerException e) {
                // swallow
            }
            if (resultConfig == null) {
                // If no result is found for the given resultCode, try to get a wildcard '*' match.
                resultConfig = results.get("*");
            }
        }

        if (resultConfig != null) {
            try {
                return objectFactory.buildResult(resultConfig, invocationContext.getContextMap());
            } catch (Exception e) {
                LOG.error("There was an exception while instantiating the result of type " + resultConfig.getClassName(), e);
                throw new XWorkException(e, resultConfig);
            }
        } else if (resultCode != null && !Action.NONE.equals(resultCode) && unknownHandlerManager.hasUnknownHandlers()) {
            return unknownHandlerManager.handleUnknownResult(invocationContext, proxy.getActionName(), proxy.getConfig(), resultCode);
        }
        return null;
    }
註釋:(1)判斷explicitResult是否爲空,不爲空直接返回,前面也解釋了 explicitResult值是什麼

(2) proxy.getConfig()獲取前面相應action的配置對象 spa

(3) config.getResults()獲取action標籤下面的result標籤的配置信息,請看 .net

gaokao-struts2-init_Traditio...加載struts.xml文件 debug

(4)results.get(resultCode)根據action的執行結果resultCode查找相應result的配置 code

(5)objectFactory.buildResult()根據上面得到result的配置,建立Result對象 orm

三、buildResult代碼:

public Result buildResult(ResultConfig resultConfig, Map<String, Object> extraContext) throws Exception {
        String resultClassName = resultConfig.getClassName();
        Result result = null;

        if (resultClassName != null) {
            result = (Result) buildBean(resultClassName, extraContext);
            Map<String, String> params = resultConfig.getParams();
            if (params != null) {
                for (Map.Entry<String, String> paramEntry : params.entrySet()) {
                    try {
                        reflectionProvider.setProperty(paramEntry.getKey(), paramEntry.getValue(), result, extraContext, true);
                    } catch (ReflectionException ex) {
                        if (LOG.isErrorEnabled())
                            LOG.error("Unable to set parameter [#0] in result of type [#1]", ex,
                                    paramEntry.getKey(), resultConfig.getClassName());
                        if (result instanceof ReflectionExceptionHandler) {
                            ((ReflectionExceptionHandler) result).handle(ex);
                        }
                    }
                }
            }
        }

        return result;
    }
註釋:(1)resultConfig.getClassName()就是result標籤屬性type對應的實現類。例如:type= dispatcher實現類就是class="org.apache.struts2.dispatcher.ServletDispatcherResult"

(2)result = (Result) buildBean(resultClassName, extraContext)經過反射機制建立result對象。

四、result 對象已經建立好了,如今就調用result.execute(this)執行方法,如今看看org.apache.struts2.dispatcher.ServletDispatcherResult

public class ServletDispatcherResult extends StrutsResultSupport {

 public ServletDispatcherResult() {
        super();
    }

    public ServletDispatcherResult(String location) {
        super(location);
    }

  public void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
        。。。
    }
}
怎麼沒有 execute方法,有什麼貓膩呢?看看他的父類StrutsResultSupport

public abstract class StrutsResultSupport implements Result, StrutsStatics {

  public void execute(ActionInvocation invocation) throws Exception {
        lastFinalLocation = conditionalParse(location, invocation);
        doExecute(lastFinalLocation, invocation);
    }

  protected abstract void doExecute(String finalLocation, ActionInvocation invocation) throws Exception;
}
原來是這樣啊!父類 StrutsResultSupport中實現了 execute()方法,而且在其中調用了抽象方法doExecute(),而自雷子類ServletDispatcherResult就能夠實現doExecute()方法,這樣利於擴展。
相關文章
相關標籤/搜索