action方法定义在action类里面,它用来映射url路径(action path),modvoc 使用命名惯例(CoC)和注解来定义action路径。默认情况下,action的路径映射由包名(package),类(class)和方法名(method)来决定的,它的惯例规则如下:
path = /action包/action类.action方法.后缀
后缀:默认情况下,后缀的值是.html,可以通过modvoc全局配置;
action方法:action路径的一部分,默认是方法名;
action类:action路径的一部分,默认是类名(非大小,多个单词下排除最后一个单词,如:类名是userAction,则路径是user);
action包名:action包名是action路径可选择的一部分。
默认情况下,每个路径的部分都是来之方法,类和包名的定义,然后,每个部分都可以明确的用相应注解值来定义。
以下是简单的实体类和方法:
@MadvocAction public class HelloAction { @Action public void world() { } }
这个action类和方法映射的路径是:/hello.world.html。正如上面所说,路径中的每个部分都可以明确的用注解值来定义,我们可以简单的修改如下:
@MadvocAction("holla") public class HelloAction { @Action("mundo") public void world() { } }
通过以上的注解配置,它的映射的路径是:/holla.mundo.html。 然而,以上都只是使用了简单的字符串来定义路径,我们可以通过以下类配置复杂的路径:
@MadvocAction("foo/boo") public class HelloAction { @Action("zoo/hello.exec") public void world() { } }
以上的配置中,它的映射路径是:/foo/boo.zoo/hello.exec.html 。
在上面的例子中,我们可以通过在一个action类写多个方法类映射多个路径。
在同一个网站中只有一个后缀是合理的,所以,我们可以在modvoc的全局配置来配置默认的后缀。但是,我们也可以通过@Action 注解的extension来定义每个方法映射的后缀:
@MadvocAction public class HelloAction { @Action(extension="jpg") public void world() { } @Action(extension=Action.NONE) public void foo() { } }
由于madvoc框架很容易扩展,它很合适来为action路径和实现自定义行为 扩展组件。例如:它很容易的为任何的方法做比如 store... 开头的扩展,或者 以.do作为结尾。
通过madvoc的@Action注解,我们可以来定义完整的action映射路径。注意:必须以前缀“/”开头。如下:
@MadvocAction public class HelloAction { @Action("/bonjour-monde.html") public void world() { } }
明显地,以上的action映射的路径是:/bonjour-monde.html。当一个action路径定义用“/”开头的时候,则说明它使用了完整的action路径,忽略了上一级或者几级的配置(如包名,类名)。
默认情况下,action包是被忽略的,没有使用在action路径中。但尽管如此,在action的包中设置为路径的一部分还是有意义的,madvoc提供了一个方法来设置包为action路径的一部分。
首先,这个特征必须在root package中开启,这样会映射到action跟的路径,这个设置在madvoc初始化的适合被设置,一个方法如下:
public class MyWebApplication extends WebApplication { @Override protected void init(MadvocConfig madvocConfig, ServletContext servletContext) { madvocConfig.getRootPackages().addRootPackageOf(IndexAction.class); } }
root Package 根据包名和路径定义。在上面的例子中,一个root package(indexAction)会映射到web的跟目录(/)。
当root package被定义,madvoc则认为action类的包:来至root package的偏移量(offset)会被当做action路径的前缀,所以,package会被映射成为一个文件夹,如下代码:
package org.jodd.madvoc.doc; @MadvocAction public class HelloAction { @Action public void world() { } }
则会被映射到/doc/hello.world.html ,如果root package被设置到org.jodd.madvoc.的话。如果你指定了多个root package,一定要注意,千万别重复映射了。
很多时候,我们想集成一些action类在分开的子包下,但是又不想改变action的路径(比如根目录),我们可以指定@MadvocAction("/")在子包下,这样,madvoc会映射这个包下所有的类到跟目录下:
@MadvocAction("/") package com.....; import jodd.madvoc.meta.MadvocAction;
默认情况下,madvoc会忽略所有的http请求方法,无论是post,get还是其他,映射到的方法都会被执行。但是,madvoc也提供了注解@Action的method来控制http请求,如下代码:
@MadvocAction public class FormAction { @Action(method = "POST") public void store() { } }
这个方法会映射到路径:/form.store.html,同时只有是post方法的时候会被执行,get或者其他方法则出现了404错误(page not found)。
通过以上的介绍,显然的,madvoc使用了action的方法来映射action的路径。此外,madvoc也考虑了一些路径和方法的名字是无关的一些默认设置,比如那些我们常用的页面,比如index.html,about.html,error.html等。madvoc会忽略 execute 和 view的方法名字,所以,一下的action:
@MadvocAction public class IndexAction { @Action public void view() { } }
则会被映射到页面 /index.html。如果有多个默认的方法被使用,madvoc会选择最后一个方法来调用,或者抛出一个异常来指明指明action路径的配置。此外,这些默认的方法名字都可以在madvoc的全局变量中自由的配置。
作为选择,注解 @Action可以被设置为“忽略”值,这样,在action路径映射的时候就会忽略这个方法的名字,因此,以下的代码中和上面的代码有相同的映射路径。
@MadvocAction public class IndexAction { @Action(Action.NONE) public void foo() { } }
接下来我们通过一个表格来总结下ActionMethodParser 的默认的行为。