Struts2 convention的特点是“约定优于配置”。开发时候遵守这些约定就可以了。
convention的安装:下载Struts2-convention-plugining-*.*.*.*.jar;然后放大WEB-INF/lib下就可以使用了。开发工具的jar包最终也是到WEB-INF/lib目录下。
好的,第一个约定你来了。convention插件会自动搜索如下包含如下名字的包名下的Java类:
1)struts; \\如:com.test.struts.myAction
2) struts2:\\如:com.test.struts2.myAction1
3) action: \\ com.test.action.myAction21
4)actions: \\com.test.action.myAction3
并且满足如下两个条件的java类当成是Action类
1)所有继承com.opensymphony.xwork2.Action的Java类
2)所有类名以Action结尾的Java类 \\如上例的红色部分为Action类,其他则不是;
当让,Convention允许你通过它的变量来改变约定以满足你的要求:
1)struts.convention.exclude.packages:指定不扫描哪些包下的Java类,位于这些包结构下的Java类将不会自动被映射成Action;
2)struts.convention.packages.locators:插件使用该常亮指定的包作为搜索Action的根包:如
actions.lee.LoginAction,按约定原本映射到/lee/login;如果将该常亮设置为lee,则映射为/login;
3)struts.convention.action.packages:convention除了会自动搜索struts,strut2,action,actions关键字包下的java类外,还会搜索该参数指定的常量下的包,并试图找到相应的Action包。
按约定映射Action的实例:
类路径 | namespace |
com.test.action.myAction | / |
com.test.action.lee.myAction | /lee |
1)如果该Action类名包含Action后缀,则将该Action类名的Action部分去掉,否则不做任何处理
2)将Action类名的驼峰写法转成中划线写法。
例如,LoginAction ------》 login
GetBooks ------>get-books
AddEmployeeAction ----> add-employee
接下来按约定映射Result
:Action处理结果后返回一个字符串的逻辑视图,这个逻辑视图要映射到实际的物理视图才有实际意义。convention也为逻辑视图和物理视图的映射提供了约定机制。
1)在默认情况下,convention会自动到WEB-INF/content下定位物理视图,定位视图的约定为:actionurl + resultstring +suffix。而当某个逻辑视图找不到对应的物理视图时候,Convention会自动试图去使用actionurl + suffix作为物理视图。
例如:action.lee.LoginAction 返回success字符串时,Convention优先考虑
WEB-INF/content/lee/目录下的login-success.jsp作为视图资源。如果找不到,login.jsp也可以作为视图资源。
对于开发者来说,为了便于调试,struts2-config-browser-plugin.*.*.*.jar包可以用于查看对应关系。
安装好之后,通过在浏览器中键入http://localhost:8080/WebAppName/config-browser/actionNames.action即可察看系统中所有的action。
-----------------------------------------------------------------------------------------------------------
接下来是Action链的映射:
如果希望一个Action处理完后不是返回视图而是转向下一个Action形成Action链,通过Convention插件只需要遵守如下三个约定即可:
1)第一个Action返回的result没有对应的视图
2)第二个Action和第一个Action处于同一个包中
3)第二个Action映射的URL为firstactionurl + resultstring
自动重加载映射:
可能有读者感觉麻烦,由于Convention插件式根据Action,JSp页面动态生成映射的,因此不管是action的改变还是jsp的改变,都需要重新加载映射。实际上,Convention完全支持自动重加载,只要为struts2应用配置如下两个常量即可(既可在web.xml文件中,也可在struts.xml中)
<!--配置Struts 2应用处于开发模式-->
<constant name="struts.devMode" value="true"/>
<!--配置Convention插件自动重加载映射-->
<constant name="struts.convention.classes.reload" value="true" />
-----------------------------------------------------------------------------------------------------------
Convention的Annotation
前面介绍的Convention 介绍的约定是在管理Action和Result映射之上;而Struts 2的配置文件除了管理Action,Result之外,还需要管理拦截器,异常处理等相关信息,Convention使用Annotation来管理这些配置。除此之外,Convention还允许使用Annotation管理Action和Result的配置,从而覆盖Convention的约定。
---------------------------------------------------------------------------------------------------------------
注意:1)使用Action后,该Action所在的包名将被忽略。而是通过参数namespace来指定URL的路径。
namespace对应的是URL路径。
而jsp中<S:action name="login" namespace="/test"> 对应也是路径。
例如convention中的com.caojian.action.mytest.LoginAction。则其URL为:
//localhost:8080/mytest/login 通过这个调用action。
而jsp中要指定上述action,需要指定如下:
<S:action name="login" namespace="/mytest">
2)而当使用convention中的annotaion的时候,也就是@action之类时候,convention中的包名被忽略,这个时候如果@namespace("/"),则上诉action的URL为:
//localhost:8080/Login。则jsp中应该为:<S:action name="login" namespace="/" />
注意:上述两种情况namespace必须指定,即<S:action name="login" namespace="path"> @namespace("path")。
3)当不使用convention插件的时候。
如果<S:action name="login" />即不指定路径的时候,struts会寻找响应的xml文件,并找到<action name="login" class="..." />从而找到对应的class《==》<action name="login" namespace="/" class="..."/> <==><action name="login" namespace="" class="..."/>
当<S:action name="login"/>找不到对应的action的时候,会到默认的namespace下找寻action,即xml中<action name="login" class="..."/>或者<action name="login" namespace="" class="..."/>
头有点晕了,再测试。