Struts2通配符和默认action冲突

Struts2找不到action的时候就会抛出一下错误:

Unable to instantiate Action, xxxxAction,  defined for 'xxxx/xxxx' in namespace '/'xxxxAction
    at com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:316)
    at com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:397)
    at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
    at org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
    at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
    at com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:553)
    at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)

几乎所有的错误日志都是这个信息,看着心里烦,而且很多网站功能去掉后,页面没有了,但是搜索引擎不知道啊,每次都一个劲地请求。于是我就配置了默认action来防止抛出这些错误信息。

但是我弄了很多次就是不成功,最后网上找到了答案,原来默认action和通配符有冲突,但是如果改通配符那就不知道要改多久了。

然后我就想写一个拦截器,但是非常不幸的事情是这个错误在进入拦截器之前就抛出来了。

不行写个过滤器,然后try-catch,但是我又不想这么做。

最后我就想干脆改一下struts2的源码算了。

ok,我们看看错误信息可以看到产生错误的地方时:DefaultActionInvocation.java:316(当然你不一定这里改的,其他地方也可以,就像上面你用过滤器加一个try-catch也是一样,但是我想的是try-catch模块越小越好)

ok,找到源代码:

throw new XWorkException(gripe, e, proxy.getConfig());

就是这一句了,我们注释掉,然后添加上一下代码:

try {
    Configuration configuration = Dispatcher.getInstance().getConfigurationManager().getConfiguration(); // 获取配置信息
    PackageConfig packageConfig = configuration.getPackageConfig(proxy.getConfig().getPackageName()); // 获取package配置
    String defaultActionRef = packageConfig.getDefaultActionRef(); // 获取默认的action的name
     
    if(defaultActionRef == null){
        throw new XWorkException("你没有配置默认action信息", e, proxy.getConfig());
    }
     
    String defaultActionClass = configuration.getRuntimeConfiguration().getActionConfig(packageConfig.getNamespace(), defaultActionRef).getClassName(); // 获取action对应的class
    String defaultActionMethod = configuration.getRuntimeConfiguration().getActionConfig(packageConfig.getNamespace(), defaultActionRef).getMethodName(); // 获取action对应的method
    action = objectFactory.buildBean(defaultActionClass, contextMap); // 获取action
     
    // 下面是修改方法
    Field method = DefaultActionProxy.class.getDeclaredField("method");
    method.setAccessible(true);
    method.set(proxy, defaultActionMethod == null ? "execute" : defaultActionMethod);
} catch (Exception ae) {
    throw new XWorkException(gripe, ae, proxy.getConfig());
}

这样就好了,不过不知道会不会存在什么安全问题啊,这我就不管了。
不过还有个麻烦事情,我对maven不是了解,打成jar比较麻烦啊。这问题下次搞了,回家过清明节了。

经过我的观察发现,还存在一个问题就是,当存在action但是访问了不存在的方法的时候,还是会抛出错误。