java.lang.NullPointerException at com.opensymphony.xwork2.util.LocalizedTextUtil.findText(LocalizedTextUtil.java:630)

为了防止CSRF攻击,在struts2的form表单中使用<s:token/>,在拦截器里添加了<interceptor-ref name=”token”/>,结果发现抛出下面的异常:

java.lang.NullPointerException
at com.opensymphony.xwork2.util.LocalizedTextUtil.findText(LocalizedTextUtil.java:630)
at com.opensymphony.xwork2.util.LocalizedTextUtil.findText(LocalizedTextUtil.java:606)
at com.opensymphony.xwork2.TextProviderSupport.getText(TextProviderSupport.java:210)
at com.opensymphony.xwork2.TextProviderSupport.getText(TextProviderSupport.java:139)
at org.apache.struts2.interceptor.TokenInterceptor.getErrorMessage(TokenInterceptor.java:182)
at org.apache.struts2.interceptor.TokenInterceptor.handleInvalidToken(TokenInterceptor.java:166)
at org.apache.struts2.interceptor.TokenInterceptor.handleToken(TokenInterceptor.java:151)
at org.apache.struts2.interceptor.TokenInterceptor.doIntercept(TokenInterceptor.java:142)
at com.alibaba.search.scc.web.interceptor.SccTokenInterceptor.intercept(SccTokenInterceptor.java:42)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:562)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)

我的用法照理讲应该是官方的用法,按照异常堆栈查看struts2源码,发现问题在这里:

出问题的是textProvider.getText方法,原因是textProvider中的bundle和class是空的,为什么是空的呢?可以看到setTextProvider方法上有一个@Inject注解,这个注解告诉了struts2需要注入一个类型为com.opensymphony.xwork2.TextProvider的实例,因为struts jar包里面的struts-default.xml中默认的配置是:

所以默认注入的就是TextProviderSupport实例对象,而这个bean中没有默认指定class和bundle,这就导致了textProvider.getText方法抛出空指针异常。

根据官方文档中的说法,可以自己实现TextProvider,形如:

<bean class=”org.demo.MyTextProvider” name=”myTextProvider” type=”com.opensymphony.xwork2.TextProvider” />

<constant name=”struts.xworkTextProvider” value=”myTextProvider” />

换个方式解决问题:

如果上面的getErrorMessage方法中执行了if语句里面的内容就不会走到textProvider.getText方法那里去,所以可以尝试让action的类型属于TextProvider,在TextProvider上ctrl+T可以看到其实现类上有ActionSupport类,所以这就知道了只需要让action类继承ActionSupport类即可避免抛出上面的空指针异常。

当然,既然进入到handleInvalidToken方法里面来了,那就需要为返回值INVALID_TOKEN_CODE(“invalid.token“)配置出错页面,形如:

 

Post Footer automatically generated by wp-posturl plugin for wordpress.



好书推荐:Java Web开发实战