最近碰到一個小要求,想讓一些action返回的resultType默認為freemarker,開始是想在action上配置全局的result,然後name用一個表達式,然後type="freemarker", 但是經過實驗,發現不行,因為這些配置是在struts2一啟動的時候就已經實例化了,再在action中使用表達式起不了作用,最後會報異常. 於是去跟蹤源碼,最後在PackageConfig這個類中找到了相關的代碼 [java] public String getFullDefaultResultType() { if ((defaultResultType == null) && !parents.isEmpty()) { for (PackageConfig parent : parents) { String parentDefault = parent.getFullDefaultResultType(); if (parentDefault != null) { return parentDefault; } } } return defaultResultType; } 這個是一個遞歸查詢,如果本包沒有配置,就會查找父包,最後會找到default-package中,這個裡面指定了為dispatcher. 好吧,代碼是找到了,那麼如何更改呢, 只需要在包中重新申明一下這個result-type [html] <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult" default="true" /> 並指定為default, 在解析這個包的時候就會將這個設置為默認的result-type. 相關代碼在com.opensymphony.xwork2.config.providers.XmlConfigurationProvider類的addResultTypes方法中. [java] protected void addResultTypes(PackageConfig.Builder packageContext, Element element) { NodeList resultTypeList = element.getElementsByTagName("result-type"); for (int i = 0; i < resultTypeList.getLength(); i++) { Element resultTypeElement = (Element) resultTypeList.item(i); String name = resultTypeElement.getAttribute("name"); String className = resultTypeElement.getAttribute("class"); String def = resultTypeElement.getAttribute("default"); Location loc = DomHelper.getLocationObject(resultTypeElement); Class clazz = verifyResultType(className, loc); if (clazz != null) { String paramName = null; try { paramName = (String) clazz.getField("DEFAULT_PARAM").get(null); } catch (Throwable t) { // if we get here, the result type doesn't have a default param defined. } ResultTypeConfig.Builder resultType = new ResultTypeConfig.Builder(name, className).defaultResultParam(paramName) .location(DomHelper.getLocationObject(resultTypeElement)); Map<String, String> params = XmlHelper.getParams(resultTypeElement); if (!params.isEmpty()) { resultType.addParams(params); } packageContext.addResultTypeConfig(resultType.build()); // set the default result type if ("true".equals(def)) { packageContext.defaultResultType(name); } } } } 這段代碼用來解析struts2的配置文件,獲得result-type元素,然後,解析相關元素,如果設置了default為true,則會將這個result-type設置為默認的.