1. 插件简介
从 Struts2.1 开始,Struts2 引入了 Convention 插件来支持零配置。该插件完全可以抛弃配置信息,不仅不需要使用 struts.xml 文件进行配置,甚至不需要使用 Annocation 进行配置,而是由 Struts2 根据约定自动配置。
2. 插件使用方法
为了使用 Convention 插件,必须在 Struts2 应用中安装 Convention 插件。安装该插件只需要将 Struts2 项目下的 strtus2-convention-plugin-2.x.xx.jar 文件复制到 Struts2 应用的 WEB-INF/lib 路径下即可。
3. “约定”支持
Convention 插件的主要特点是“约定优于配置”。学习 Convention 插件其实非常简单,关键是记住 Convention 插件的约定,开发时准遵守这些约定即可。
3.1 action 的搜索和映射约定
3.1.1 action 的搜索
对于Convention 插件而言,默认情况下,它会自动搜索位于 action、actions、struts、struts2 包下的所有 Java 类,Convention 插件会把如下两种 Java 类当成Action 处理:
- 所有实现了 com.opensymphony.xwork2.Action 的 Java 类。
- 所有类名以 Action 结尾的 Java 类。
下面这些类都是符合 Convention 插件约定的 Action 类
// 未实现了 com.opensymphony.xwork2.Action 接口
- app.web.actions.LoginAction
// 实现了 com.opensymphony.xwork2.Action 接口
- app.web.action.demo.HelloWorld
- app.web.actions.LoginAction
- app.web.struts.first.DemoAction
- app.web.struts2.demo.test.Test
Struts2 的 Convention 插件还允许设置如下常量来改变插件默认的搜索范围:
- struts.convention.exclude.packages:指定不扫描哪些包下的 Java 类。位于这些包结构下的 Java 类将不会被映射成 Action。
- struts.convention.action.packages:Convention 插件以该常量指定包作为根包来搜索 Action 类。Convention 插件除了扫描 action、actions、struts、struts2 四个包的类之外,还会扫描该常量指定的一个或多个包,Convention 会试图从中发现 Action 类进行映射。
action 类的搜索规则总结:
对于一个 Java 类,只要此类位于 action/actions/struts/struts2 包及其子包下(可以通过上述两个常量进行过滤、修改和追加),并且实现 com.opensymphony.xwork2.Action 接口或者类名以 Action 结尾,都会被 Convention 插件搜索到,并进行映射。
3.1.2 action 映射约定
在找到合适的 Action 类之后,Convention 插件会按约定部署这些 Action。部署 Action 时,action、actions、struts、struts2 包会映射成根命名空间,而这些包下的子包则被映射成对应的命名空间。
Action 的 name 属性(也就是该 Action 所要处理的 URL)则根据该 Action 的类名映射,主要遵循如下两步规则:
- 如果该 Action 类名包含 Action 后缀,将该 Action 类名的 Action 后缀去掉;否则不做任何处理。
- 将 Action 类名的驼峰写法(每个单词首字母大写、其他字母小写的写法)转成中划线写法(所有字母小写,单词与单词之间以中划线隔开)。
例如,如下的 Action 类被自动映射的访问路径 URL 如下:
// 未实现了 com.opensymphony.xwork2.Action 接口
- app.web.actions.LoginAction 映射到:/login.action
// 实现了 com.opensymphony.xwork2.Action 接口
- app.web.action.demo.HelloWorld 映射到:/demo/hello-world.action
- app.web.actions.LoginAction 映射到:/login.action
- app.web.struts.first.DemoAction 映射到:/first/demo.action
- app.web.struts2.demo.test.Test 映射到:/demo/test/test.action
Struts2 的 Convention 插件还允许设置如下常量来改变插件默认的根命名空间:
- struts.convention.package.locators:Convention 插件使用该常量指定的包作为搜寻 Action 的根包(根命名空间)。默认情况下,action、actions、struts、struts2 包会映射成根命名空间,通过此常量,可以在原有基础上修改或追加根命名空间。对于 app.web.action.demo.test.Test 类,按约定原本应映射到 /demo/test;如果该常量设置为 demo,则该 Action 会映射到 /test。
3.2 result 映射约定
Action 处理用户请求之后会返回一个字符串作为逻辑视图该逻辑视图必须映射到实际的物理视图才有意义。Convention 默认也为为作为逻辑视图和物理视图之间的映射提供了约定。
默认情况下,Convention 总会到 Web 应用的WEB-INF/content 路径下定位物理资源,定位资源的约定是:actionName + resultCode + suffix,当某个逻辑视图找不到对应的视图资源时,Convention 会自动试图使用 actionName + suffix 作为物理视图资源。
例如:app.web.struts.LoginAction 返回 SUCCESS,Struts 会依次查找如下结果页面:
- /WEB-INF/content/login-success.jsp
- /WEB-INF/content/login-success.html
- /WEB-INF/content/login.jsp
- /WEB-INF/content/login.html
说明:
- 对于返回的不同逻辑视图名(success/error/input等),resultCode 取相应的值;
- 对于返回的不同结果类型(Dispatcher/FreeMarker/velocity 等),suffix 取对应的值(jsp/ftl/vm 等);
- 关于默认的物理资源路径,可通过常量修改:struts.convention.result.path,默认为 /WEB-INF/content。
3.3 action 链约定
如果希望一个 Action 处理结束后不是进入视图页面,而是进行另一个 Action 形成的 Action 链,则通过 Convention 插件只需遵守如下的三个约定即可:
- 第一个 Action 返回的逻辑视图字符串(resutlCode)没有对应的视图资源。
- 第二个 Action 与第一个 Action 处于同一个包下。
- 第二个 Action 映射的 URL 为:firstActionName - resultCode
例如:
第一个 Action 类名为:FirstAction,返回的物理资源视图为:“second”,则第二个 Action 的类名为 FirstSecondAction,映射的 URL 为 /first-second.action。(注:指定的物理资源路径下不能存在 “second” 对应的物理视图资源,两个 Action 处在同一个包下)
4. 自动加载映射
由于 Convention 插件是根据 Action、JSP 页面来动态生成映射的,因此不管是 Action 的改变,还是 JSP 页面的改变,都需要 Convention 插件重新加载映射。Convention 插件提供了常量来支持自动重新加载映射。
struts.convention.classes.reload = true
注意:
- 对于上述参数,要使其生效,需要先打开 Struts2 的开发者模式
- 对于此 Convention 插件参数,官方建议慎用,在 Tomcat7 上会引发 NullPointException(未测试)
5. convention 插件相关常量
常量名 | 说明 |
---|---|
struts.convention.action.disableJarScanning | 设置是否从 Jar 包里搜索 Action 类。如果开发者喜欢将 Action 类打包丰 JAR,则应将该常量设为 true。默认值为 false |
struts.convention.action.packages | Convention 插件以该常量指定的包作为根包来搜索 Action 类。 |
struts.convention.result.path | 设置 Convention 插件定位视图资源的根路径。默认为 /WEB-INF/content。 |
struts.convention.result.flatLayout | 如果设置为 false,遇可以将视图页面放置到 Action 对应的目录下(无须放入 /WEB-INF/content。)默认值为 true。 |
struts.convention.action.suffix | Convention 搜索 Action 类名后缀。默认值为 Action。 |
struts.convention.actin.disableScanning | 是否禁止通过包扫描 Action。默认为 false。 |
struts.convention.action.mapAllMatches | 设置即使没有 @Action注解,依然创建 Action 映射。默认值是 false。 |
struts.convention.action.checkImplementAction | 设置是否将实现 Action 接口的类映射成 Action。默认值是 true。 |
struts.convention.action.parent.package | 设置 Convention 映射的 Action 所在饭默认父包。默认值是 convention-default。 |
struts.convention.action.name.lowercase | 设置映射 Action 时,是否将 Action 的 name 属性值转为所有字母小写。默认值是 true。 |
struts.convention.action.name.separator | 设置映射 Action 时指定 name 属性值各单词之间的分隔符。默认值是中划线 |
struts.convention.package.locators | Convention 插件使用该常量指定的包作为搜寻 Action 的根包。默认值是 action,actions,struts,struts2 |
struts.convention.package.locators.disable | 指定禁止从 Action 的根包里搜寻 Action。默认值是 false。 |
struts.convention.exclude.packages | 指定排除在搜索 Action之外的包。默认值为 org.apache.struts.*,org.apache.struts2.*,org.springframework.web.struts.*,org.springframework.web.strut2.*,org.hibernate.* |
struts.convention.package.locators.basePackage | 如果指定了该常量,Convention 只会从以该常量值开始的包中搜索 Action 类 |
struts.convention.relative.result.types | 指定 Convention 映射 Result 时默认支持的结果类型。默认值是 dispatcher,velocity,freemarker |
struts.convention.redirect.to.slash | 设置重定向到斜线(/)。例如,@Result(location=”/test.jsp”) ,会在 “server/项目名/” 这个路径下找 test.jsp,注解中不加 “/”,则会在 struts.convention.result.path 这个常量配置的路径下找。若设为 false,则 “/” 无效。默认值是 true。 |