SSH Exception

关于Struts2、Spring、Hibernate三大框架整合中碰到的异常


没有匹配名称空间[/]的Action

异常信息:

no action

这个异常应该很多开发者都遇到过,出现这个异常的原因有很多种,我自己也尝试着结合自己遇到的问题以及前人的经验总结了一下可能会造成这个问题的因素:

检查struts.xml配置文件,包括文件的名称是否写错、文件路径(src)是否正确,文件的配置是否正确

检查web.xml文件,包括默认的欢迎页面的配置、struts过滤器的配置

检查动态方法调用的配置

检查struts约束文件版本

按照以上思路逐一排查,首先想到的肯定是struts.xml文件,文件名正确,路径也没问题,之后检查配置似乎也没有问题,完了之后检查web.xml文件,过滤器的配置以及默认首页的配置都没问题,郁闷了两分钟!完事之后想了下,我在struts.xml配置了使用通配符访问Action中方法,即:

1
2
3
<action name="UserAction_*" class="com.my.web.action.UserAction" method="{1}">
<result name="success">/success.jsp</result>
</action>

会不会是这里出现问题?之后在struts.xml中开启了动态方法调用,即

1
struts.enable.DynamicMethodInvocation = true

这一配置默认情况下是false,启用后我以为能解决问题,是事实然并卵,又郁闷了两分钟!最后发现网上有人也遇到了这种问题,说有可能是约束文件的版本问题,2.3之后的约束在使用通配符方法Action中的方法的时候,还需要额外配置一个选项<allowed-methods>,在此元素中配置允许通过通配符进行访问的方法,即:

1
<allowed-methods>方法名1,方法名2...</allowed-methods>

检查我自己的约束文件发现,我使用的2.5版本的约束,配置了allowed-methods之后,发现可以正常访问了。


空指向异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
java.lang.NullPointerException
at com.my.web.action.CustomerAction.list(CustomerAction.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:899)
at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1544)
at ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68)
at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethodWithDebugInfo(XWorkMethodAccessor.java:98)
at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethod(XWorkMethodAccessor.java:90)
at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1620)
at ognl.ASTMethod.getValueBody(ASTMethod.java:91)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
at ognl.SimpleNode.getValue(SimpleNode.java:258)
at ognl.Ognl.getValue(Ognl.java:470)
at ognl.Ognl.getValue(Ognl.java:434)
at com.opensymphony.xwork2.ognl.OgnlUtil$3.execute(OgnlUtil.java:374)

在Spring与中Struts2整合之后,如果Action的生命周期完全由Spring来管理,并且Action中存在有依赖属性,那么在struts.xml中配置Action时,class属性的值必须与Spring的配置文件applicationContext.xmlbean元素的name属性的值一致,否则将报空指针。比如,我在struts.xml配置了一个action:

struts.xml 错误的配置
1
2
3
4
5
6
7
8
9
10
<package name="crm" namespace="/" extends="struts-default">
<!-- 将Action对象的创建交给spring容器来处理 -->
<constant name="struts.objectFactory" value="spring"></constant>
<!-- 此处的class属性的值必须与Spring的配置文件`applicationContext.xml`中`bean`元素的`name`属性的值一致 -->
<action name="CustomerAction_*" class="com.my.web.action.CustomerAction" method="{1}">
<result name="list">/jsp/customer/list.jsp</result>
<result name="error">/error.jsp</result>
<allowed-methods>list</allowed-methods>
</action>
</package>
applicationContext.xml
1
2
3
<bean name="customerAction" class="com.my.web.action.CustomerAction" scope="prototype">
<property name="cs" ref="customerService"></property>
</bean>

这里出现空指针表上面是因为action中class属性值与bean中name属性值不一致,实质上是因为在Action中声明了Service层的对象,因为如果在Action中没有声明Service层的对象,没有产生依赖,那么在struts.xml中的action元素class属性是可以通过完整类名来配置的,这样的话Action就会由Struts2负责创建而不是由Spring来创建。

struts.xml 正确的配置
1
2
3
4
5
6
7
8
9
10
<package name="crm" namespace="/" extends="struts-default">
<!-- 将Action对象的创建交给spring容器来处理 -->
<constant name="struts.objectFactory" value="spring"></constant>
<!-- 此处的class属性的值必须与Spring的配置文件`applicationContext.xml`中`bean`元素的`name`属性的值一致 -->
<action name="CustomerAction_*" class="customerAction" method="{1}">
<result name="list">/jsp/customer/list.jsp</result>
<result name="error">/error.jsp</result>
<allowed-methods>list</allowed-methods>
</action>
</package>

如果您觉得我的文章对您有帮助,请随意赞赏,您的支持将鼓励我继续创作!
0%