自由的映射路由,像 Spring MVC 那样。
当前版本还需要有完善的地方,暂时没有同步到**仓库. 可以通过以下仓库引用最新版本(1.0-SNAPSHOT)。
<repository>
<id>freeroute-snapshot</id>
<name>Freeroute Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
当前最新版本 1.0-SNAPSHOT
<dependency>
<groupId>com.bastengao.freeroute</groupId>
<artifactId>struts2-freeroute-plugin</artifactId>
<version>${version}</version>
</dependency>
如果你需要与 struts2-spring-plugin 结合使用,只需要以下依赖
<dependency>
<groupId>com.bastengao.freeroute</groupId>
<artifactId>struts2-freeroute4spring</artifactId>
<version>${version}</version>
</dependency>
struts.xml
<struts>
<constant name="struts.freeroute.controllerPackage" value="org.example"/>
</struts>
org.example.BookController.java
public class BookController{
private int id;
private Book book;
@Route("/books/{id}")
public String show(){
book = bookDao.find(id);
return "dispatcher:/book.jsp"
}
//setter, getter
}
webapp/book.jsp
<!DOCTYPE html>
<html>
<head>
<title>show book</title>
</head>
<body>
<h1>Hello book</h1>
</body>
</html>
访问 "/books/13", 则会显示 book.jsp 的内容
属性 | 可选 | 描述 | 默认 |
---|---|---|---|
struts.freeroute.controllerPackage | 必须 | 配置 Controller 所在的包, 插件会在此包下查找相应的 Controller,包括子包 | 无 |
struts.freeroute.controllerSuffixes | 可选 | 配置 Controller 的后缀。只解析 controllerPackage 下所有以 Controller 结尾的类。 可指定多个后缀,中间用逗号隔开 | Controller |
struts.freeroute.defaultParentPackage | 可选 | 配置默认的父包 | struts-defualt |
struts.freeroute.contentBase | 可选 | 配置全局的内容基路径,类似于 @ContentBase。 如果返回结果中路径是相对地址,则通过内容基路径将其转换为绝对路径。 如果 controller 类上有 @ContentBase 注解则优先使用。 | 无 |
struts.xml
<struts>
<constant name="struts.freeroute.controllerPackage" value="org.example"/>
<!-- 将默认 Controller 改为 Action 和 Controller -->
<constant name="struts.freeroute.controllerSuffixes" value="Action, Controller"/>
<constant name="struts.freeroute.contentBase" value="/pages/content"/>
<constant name="struts.freeroute.defaultParentPackage" value="my-struts"/>
<package name="my-struts" extends="struts-default">
</package>
</struts>
配置struts.freeroute.controllerPackage
后, 会在此包中默认搜索以Controller
结尾的类做为 Controller,
并在其中查找所有@Route
注解的方法做为路由映射.
在Controller
任意方法上加@Route
注解则表示一条路由.
例如:
public MyController{
@Route("/helloworld")
public String hello(){
return "dispatcher:/world.html";
}
}
- 简单路径映射
/helloworld
=> http://HOST:PORT/helloworld
@Route("/helloworld")
- 路径中包含变量(pathVariable)
变量可以是英文,数字,中文和 - _ ~ .
这四个标点符号(其他标点符号都不支持,参考List_of_allowed_URL_characters)。
/users/{id}
=> http://HOST:PORT/users/1013
// id将会赋予{id}变量值
private int id;
@Route("/users/{id}")
public String user(){
//...
}
// setter, getter
/users/{id}/tags/{name}
=> http://HOST:PORT/users/1013/tags/free
// {id}
private int id;
// {name}
private String name
@Route("/users/{id}/tags/{name}")
public String tagedUser(){
//....
}
// setter, getter
注意:路径变量比参数的优先级高, 上面的例子中请求如果是 http://HOST:PORT/users/1013/tags/free?name=never
, controller 中的 name 属性值将会是 free
而不是 never
。
通过在属性上加 @CookieValue
注解绑定某个 cookie 的值
//如果有 name 为 id 的 cookie 存在,那么将会把 cookie 的值绑定给 userId 属性
@CookieValue("id")
private String userId;
@Route("/users")
public String show(){
//...
}
// setter, getter
通过@Route.method
指定 HTTP method, 匹配满足 HTTP method 的路由映射
method 目前有以下类型:
- DELETE
- GET
- HEAD
- OPTIONS
- POST
- PUT
- TRACE
@Route.method
默认表示匹配任意一种 HTTP method.
只响应 POST 请求, POST http://HOST:PORT/users
@Route(value = "/users", method = MethodType.POST)
或者只响应 GET 和 POST 请求, GET|POST http://HOST:PORT/users
@Route(value = "/users", method = {MethodType.GET, MethodType.POST})
通过@Route.params
指定 HTTP param , 匹配满足 HTTP param 的路由映射
只响应带 'order' 参数的请求, GET http://HOST:PORT/users?order=time
@Route(value = "/users", params = {"order"})
可以有多个参数, GET http://HOST:PORT/users?order=time&page=13
@Route(value = "/users", params = {"order", "page"})
参数存在且等于某个值, GET http://HOST:PROT/users?name=basten
@Rotue(value = "/users", params = {"name=basten"})
参数存在但不等于某个值, GET http://HOST:PROT/users?name=basten
将会产生 404,如果 name 是其他值则不会
@Rotue(value = "/users", params = {"name!=basten"})
Controller.routeMethod
方法的返回值将决定返回的结果类型和页面路径, 如dispatcher:/example.html
, 类型为 dispatcher
, 页面路径为 /example.html
.
两种方式:
-
字面值
例如
dispatcher:/example.html
,这种方式只要返回type:location
或者直接返回type
。 -
DSL
通过
Results
和Result
等 DSL 方式的 api 构造返回结果。Results
能够满足常用返回结果。例如:Results.html("/example.html")
或者Results.html("/example")
后缀自动补全(包括 html, jsp, freemarker(ftl), velocity(vm))Results.jsp("/exmaple.jsp")
Results.json().includeProperties("value1, value2").done()
不过有时候
Results
未覆盖的情况,也可以通过Result
来组织返回结果。例如:Result.create("json") .param("includeProperties", "value1, value2") .done();
目前支持以下类型:
- dispatcher
- html
- jsp
- redirect
- chain
- httpHeader
- stream
- velocity
- freemarker
- json
页面路径以 "/" 开始
@Route("/very-long-page-path")
public String show(){
return "dispatcher:/very/long/page/path/example.html";
}
@Route("/anothor-very-long-page-path")
public String show2(){
return "dispatcher:/very/long/page/path/example2.html";
}
页面路径不是以 "/" 开始,其地址相对于 @ContentBase 的路径
@ContentBase("/very/long/page/path")
public class ExampleController{
@Route("/very-long-page-path")
public String show(){
return "dispatcher:example.html";
}
@Route("/anothor-very-long-page-path")
public String show2(){
return "dispatcher:example2.html";
}
}