最近碰到一个小要求想让一些action返回的resultType默认为freemarker开始是想在action上配置全局的result然后name用一个表达式然后type=freemarker
但是经过实验发现不行因为这些配置是在struts一启动的时候就已经实例化了再在action中使用表达式起不了作用最后会报异常
于是去跟蹤源码最后在PackageConfig这个类中找到了相关的代码
[java]
public String getFullDefaultResultType() {
if ((defaultResultType == null) && !parentsisEmpty()) {
for (PackageConfig parent : parents) {
String parentDefault = parentgetFullDefaultResultType()
if (parentDefault != null) {
return parentDefault;
}
}
}
return defaultResultType;
}
这个是一个递归查询如果本包没有配置就会查找父包最后会找到defaultpackage中这个里面指定了为dispatcher
好吧代码是找到了那么如何更改呢
只需要在包中重新申明一下这个resulttype
[html]
<resulttype name=freemarker
class=orgapachestrutsviewsfreemarkerFreemarkerResult
default=true />
并指定为default
在解析这个包的时候就会将这个设置为默认的resulttype
相关代码在comopenfigprovidersXmlConfigurationProvider类的addResultTypes方法中
[java]
protected void addResultTypes(PackageConfigBuilder packageContext Element element) {
NodeList resultTypeList = elementgetElementsByTagName(resulttype)
for (int i = ; i < resultTypeListgetLength() i++) {
Element resultTypeElement = (Element) em(i)
String name = resultTypeElementgetAttribute(name)
String className = resultTypeElementgetAttribute(class)
String def = resultTypeElementgetAttribute(default)
Location loc = DomHelpergetLocationObject(resultTypeElement)
Class clazz = verifyResultType(className loc)
if (clazz != null) {
String paramName = null;
try {
paramName = (String) clazzgetField(DEFAULT_PARAM)get(null)
}
catch (Throwable t) {
// if we get here the result type doesnt have a default param defined
}
ResultTypeConfigBuilder resultType = new ResultTypeConfigBuilder(name className)defaultResultParam(paramName)
location(DomHelpergetLocationObject(resultTypeElement))
Map<String String> params = XmlHelpergetParams(resultTypeElement)
if (!paramsisEmpty()) {
resultTypeaddParams(params)
}
packageContextaddResultTypeConfig(resultTypebuild())
// set the default result type
if (trueequals(def)) {
packageContextdefaultResultType(name)
}
}
}
}
这段代码用来解析struts的配置文件获得resulttype元素然后解析相关元素如果设置了default为true则会将这个resulttype设置为默认的