天天看点

Struts2系列之三:注解式Action

struts2是的配置文件是struts.xml,可以将Action的URL映射和结果放在该文件中,也可以通过Convention Plugin支持注解方式来配置URL映射和结果。

使用时需要把Convention Plugin添加到classpath中;如果是maven工程则添加依赖:

Convention Plugin:顾名思义,就是一种约定的插件。用户按照约定编写代码即可。

[size=medium]一、Convention Plugin约定:[/size]

[b]1. 包扫描[/b]

包路径包含action,actions,struts,struts2的所有包都会被struts当作含有Action类的路径来搜索,可以更改:

[b]2. 类匹配[/b]

从包扫描找到的package及其子package寻找com.opensymphony.xwork2.Action的实现类或后缀为Action的类:如:

[b]3. 命名空间[/b]

命名空间就是URL中上下文和Action之间的部分,如http://localhost:8080/vehicle/car/buy.action,这里的命名空间就是/car

和SpringMVC通过类和方法的@RequestMapping注解来定义命名空间不同,struts2的命名空间默认是locators标示到包结束的部分:

注:如果包路径包含一个以上的locators,以第一个作为标示,其余的作为命名空间的组成部分。如:

[b]4. Action映射URL约定[/b]

去掉类名中的Action部分,然后将其它部分(每个都以大写开头)转换为小写,之间默认以'-'连接,可以通过下面常量更改分隔符:

如QuickBuyAction,去掉Action后,为QuickBuy,以大写字母,分成两个部分:Quick, Buy,转换成小写后,再以'-'连接,即为:quick-buy

通过上面的几个步骤,能够根据类的全限定名确定访问URL。以下URL省略主机名、端口和上下文,后缀为.do

[b]5. 结果模板页存放路径[/b]

默认在/WEB-INF/content下,可以通过下面的常量配置:

当执行下面的execute方法时:

a. struts2会到path+命名空间(/WEB-INF/jsp/action/car)的路径下优先寻找 去除Action后缀之后,以separator标志('-')分隔的小写类名(quick-buy)-视图名称(success).文件扩展名(jsp)的文件。

b. 没有则试着搜寻前半部分(quick-buy.jsp)。

c. 再没有则搜索后半部分(success.jsp),还没有就报[color=red]404[/color]错误。

注:[color=red]文件路径包含命名空间[/color]

[b]6. 支持模板文件[/b]

struts2支持.html, .htm, .vm, .ftl, .jsp格式的文件,以下为映射:

[table]

|[color=darkblue]URL[/color] |[color=darkblue]Result[/color] |[color=darkblue]File that could match[/color]|[color=darkblue]Result Type[/color]|

|/hello|success |/WEB-INF/content/hello.jsp|Dispatcher|

|/hello|success |/WEB-INF/content/hello-success.htm|Dispatcher|

|/hello|success |/WEB-INF/content/hello.ftl|FreeMarker|

|/hello-world |input |/WEB-INF/content/hello-world-input.vm |Velocity|

|/test1/test2/hello |error |/WEB-INF/content/test/test2/hello-error.html |Dispatcher|

[/table]

[size=medium]二、注解配置[/size]

有时候约定不能满足项目需要,Convention Plugin通过以下几个注解来实现自定义配置:

[b]1. @Namespace[/b]

标注在Action类上,[color=red]覆盖[/color]约定的命名空间。

未加@Namespace前:

[table]

|方法名 |默认调用路径 |默认映射路径|

|execute |/action/myns/my!execute.do |/WEB-INF/content/action/myns/my-error.jsp|

[/table]

添加@Namespace后,可以看出,[b]调用和映射路径中的命名空间都被覆盖[/b]了:

[table]

|方法名 |@Namespace注解后调用路径 |@Namespace注解后映射路径|

|execute |[color=red]/open[/color]/my!execute.do |/WEB-INF/content[color=red]/open[/color]/my-error.jsp|

[/table]

注:此时访问/action/myns/my.do(不经过方法),还是能找到/WEB-INF/content/action/myns/my.jsp

[b]2. @Action和@Actions[/b]

将URL映射到指定方法,[color=red]扩展[/color]约定配置

[code]

package com.john.struts2.action;

import org.apache.struts2.convention.annotation.Action;

import org.apache.struts2.convention.annotation.Actions;

import com.opensymphony.xwork2.ActionSupport;

public class KittyAction extends ActionSupport {

@Action("action1")

public String acid() {

return SUCCESS;

}

@Action("/user/action2")

public String sweet() {

return SUCCESS;

}

@Action("/autumn/summer/action3")

public String bitter() {

return SUCCESS;

}

@Actions({ @Action("/one/url"), @Action("/another/url") })

public String pungent() {

return SUCCESS;

}

}

[/code]

未加@Action前:

[table]

|方法名 |默认调用路径 |默认映射路径|

|acid |/action/kitty!acid.do |/WEB-INF/content/action/kitty-success.jsp|

|sweet |/action/kitty!sweet.do |/WEB-INF/content/action/kitty-success.jsp|

|bitter |/action/kitty!bitter.do |/WEB-INF/content/action/kitty-success.jsp|

|pungent|/action/kitty!pungent.do |/WEB-INF/content/action/kitty-success.jsp|

[/table]

添加@Action后,在上面的基础上[b]扩展新的调用和映射路径[/b]:

[table]

|方法名 |@Action后调用路径 |@Action后映射路径|

|acid |/action/action1!acid.do |/WEB-INF/content/action/action1-success.jsp|

|sweet |[color=red]/user[/color]/action2!sweet.do |/WEB-INF/content[color=red]/user[/color]/action2-success.jsp|

|bitter |[color=red]/autumn[/color]/summer/action3!bitter.do |/WEB-INF/content[color=red]/autumn[/color]/summer/action3-success.jsp|

|pungent|[color=red]/one[/color]/url!pungent.do |/WEB-INF/content[color=red]/one[/color]/url-success.jsp|

|pungent|[color=red]/another[/color]/url!pungent.do |/WEB-INF/content[color=red]/another[/color]/url-success.jsp|

[/table]

注:

i. @Action[color=red]标注在方法[/color]上,却是对[color=red]类名映射路径的扩展[/color]。上面的KittyAction约定映射是kitty,同时也可以是@Action指定的映射,如/action1

ii. @Action[color=red]不会覆盖[/color]原来的约定配置,如标注了@Action的acid方法,通过/kitty!acid还是可以访问的。

iii. @Action的值如果包含一个以上的路径分隔符(/),会用[color=red]第一个路径子串替代默认命名空间,之后的路径子串替代Action类的约定映射[/color],如:

@Action("/user/action2"),/user替代/action,/action2替代kitty

@Action("/autumn/summer/action3"),/autumn替代action,/summer/action3替代kitty

iv. @Actions是@Action的数组形式,可以将[color=red]多个URL和一个方法关联[/color]

[b]3. @Results和@Result[/b]

[b]类级别(global)[/b]

标注在Action类上,结果映射可以被action类的所有方法共享。

[table]

|方法名 |调用路径 |返回视图|

|travel |/action/national-day!travel.do |/WEB-INF/enjoyable.jsp|

|home |/action/national-day!home.do |/WEB-INF/enjoyable.jsp|

|home |[color=red]/cozy[/color]/fragrant!home.do |/WEB-INF/enjoyable.jsp|

[/table]

[b]方法级别(local)[/b]

以@Action的results属性呈现,结果映射只能由被标注方法所用。

[table]

|方法名 |调用路径 |返回视图|

|wedding |/action/national-day!wedding.do |/WEB-INF/content/action/national-day-happiness.jsp|

|wedding |/happy/blessing!wedding.do |/WEB-INF/conjugal.jsp|

[/table]

继续阅读