Convention 插件(1)

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 的类名映射,主要遵循如下两步规则:

  1. 如果该 Action 类名包含 Action 后缀,将该 Action 类名的 Action 后缀去掉;否则不做任何处理。
  2. 将 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 会依次查找如下结果页面:

  1. /WEB-INF/content/login-success.jsp
  2. /WEB-INF/content/login-success.html
  3. /WEB-INF/content/login.jsp
  4. /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

注意:

  1. 对于上述参数,要使其生效,需要先打开 Struts2 的开发者模式
  2. 对于此 Convention 插件参数,官方建议慎用,在 Tomcat7 上会引发 NullPointException(未测试)

5. convention 插件相关常量

常量名说明
struts.convention.action.disableJarScanning设置是否从 Jar 包里搜索 Action 类。如果开发者喜欢将 Action 类打包丰 JAR,则应将该常量设为 true。默认值为 false
struts.convention.action.packagesConvention 插件以该常量指定的包作为根包来搜索 Action 类。
struts.convention.result.path设置 Convention 插件定位视图资源的根路径。默认为 /WEB-INF/content。
struts.convention.result.flatLayout如果设置为 false,遇可以将视图页面放置到 Action 对应的目录下(无须放入 /WEB-INF/content。)默认值为 true。
struts.convention.action.suffixConvention 搜索 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.locatorsConvention 插件使用该常量指定的包作为搜寻 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。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Struts2中使用Convention插件配置权限拦截器,可以按照以下步骤操作: 1. 在`struts.xml`文件中配置一个拦截器栈,例如: ```xml <struts> <constant name="struts.convention.action.packages" value="com.example.actions"/> <package name="default" extends="struts-default"> <interceptors> <interceptor-stack name="myStack"> <interceptor-ref name="authInterceptor"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> </package> </struts> ``` 2. 定义一个权限拦截器`authInterceptor`,例如: ```xml <struts> <constant name="struts.convention.action.packages" value="com.example.actions"/> <package name="default" extends="struts-default"> <interceptors> <interceptor-stack name="myStack"> <interceptor-ref name="authInterceptor"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> <interceptor name="authInterceptor" class="com.example.interceptors.AuthInterceptor"/> </interceptors> </package> </struts> ``` 3. 在`com.example.interceptors.AuthInterceptor`类中实现权限验证逻辑,例如: ```java public class AuthInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { // 获取当前请求的Action和方法名 String actionName = invocation.getProxy().getActionName(); String methodName = invocation.getProxy().getMethod(); // 根据Action和方法名判断是否需要进行权限验证 boolean needAuth = checkNeedAuth(actionName, methodName); // 如果需要权限验证,则进行验证 if (needAuth) { // TODO: 实现权限验证逻辑 // 如果权限验证不通过,则返回一个特定的结果 return "authFailed"; } else { // 如果不需要权限验证,则直接执行Action return invocation.invoke(); } } private boolean checkNeedAuth(String actionName, String methodName) { // TODO: 根据Action和方法名判断是否需要进行权限验证 return true; } } ``` 4. 在需要进行权限验证的Action类或方法上添加`@InterceptorRefs`注解,指定使用的拦截器栈,例如: ```java @Namespace("/admin") @InterceptorRefs("myStack") public class AdminAction extends ActionSupport { @Action("/listUsers") public String listUsers() { // TODO: 实现列出用户列表的业务逻辑 return SUCCESS; } } ``` 这样,当用户访问`/admin/listUsers`时,就会先被`authInterceptor`拦截器拦截,进行权限验证,如果验证通过,则执行`listUsers`方法,否则返回`authFailed`结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值