标签:
我使用的Struts2的版本是2.5.2,今天在使用Struts2的DMI(动态方法调用)的时候出现了一个有趣的问题,我先把我的配置及代码展示一下:
web.xml
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
struts.xml
<struts> <constant name="struts.devMode" value="true" /> <package name="myPack" namespace="/" extends="struts-default"> <action name="index"> <result name="success">/index.jsp</result> </action> <action name="path" class="com.stone.action.PathAction"> <result name="path">/path.jsp</result> </action> </package> </struts>
PathAction
public class PathAction { public String foo() { return "path"; } }
index.jsp
<body> <a href="path/path!foo">link</a> </body>
当我点击index页面的链接的时候得到如下错误页面:
这是因为从Struts2.3开始,DMI默认是禁用的,Apache Struts项目的官方解释如下:
从Struts2.3开始,我们增加了一个开关来控制DMI,我们这样做基于两个原因:
1. 如果Action的实现是纯POJO方式(既不继承自ActionSupport也不实现Action接口),这种场景下使用DMI可能导致安全问题。
2. DMI功能跟使用通配符配置Action类的方法有重叠的地方,而通配符配置的方式早在Struts1就有了。
如果你有安全性的顾虑或更喜欢通配符配置方式的话,请在struts.xml中做如下设置:<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
该开关默认是关闭DMI的,为了使用DMI,我必须在我的struts配置文件中将其打开,但是打开后我又得到了另外一个错误:
也就是说我在PathAction类里面定义的foo方法是不被允许的,那到底哪些方法是允许的呢?这里面就需要讲到Struts2.5新增的SMI(严格方法调用),官方文档说是扩展DMI,但是个人感觉新增的SMI更像把DMI边缘化了,SMI的大体使用方式就是,如果你想用DMI的方式调用Action的方法,那么该方法名必须显示地在Struts配置文件中定义,可以写方法名或是使用通配符等等,我使用了如下简单的方式来配置:
<action name="path" class="com.stone.action.PathAction"> <result name="path">/path.jsp</result> <allowed-methods>foo</allowed-methods> </action>
再次执行,果然可以了。
总体来说,Struts2.5新增的SMI概念还是出于安全性的考量,这样就不会让客户端想要调用Action中哪个方法都可以。
标签:
原文地址:http://www.cnblogs.com/stonefeng/p/5808664.html