九、注解路由
Voovan 自3.0版本开始提供了,对注解路由的支持,类似一个超轻量话版本的 Spring mvc. 为快速开发 resetful 和 web 应用提供支持。注解路由通俗的说就是通过在开发过程中为类或者方法添加注解的方式实现 Http 请求对应的路由自动发现和注册,不用再像以前一样在专门的 json/xml 配置文件中手工指定路由.
一、如何让Voovan WebServer支持注解路由?
Voovan 的注解路由是采用 Voovan WebServer的一个模块的形式开发的,所以我们需要在 web.json 中配置一套注解路由的模块支持。
"Modules": [
{
"Name": "注解路由模块", //模块名称
"Path": "/", //模块路径
"ScanRouterPackage": "org.voovan.test.http.router",//注解形式的路由扫描的包路径, 默认: null, 不设置这个属性则会被任务不开启
"ScanRouterInterval": 30,//注解形式的路由扫描的包路径的时间间隔. 默认:0秒. 0:关闭
"ClassName": "org.voovan.http.server.module.annontationRouter.AnnotationModule", //模块类
}
]
以上的配置,大家看看注释应该就比较清晰了,主要就是最后三个参数,涉及到注解形式的路由扫描的包路径
,扫描的包路径的时间间隔
, 注解路由的模块类
。只有在注解形式的路由扫描的包路径
中的类,且包含@Route 注解的类和方法会被注册到 Voovan WebServer 的路由的路由中。 接下来我们就需要编写带有路由注册注解的类和方法即可实现路由的响应,Voovan 会自动扫描带有这些注解标签的类,并将其注册成为 Voovan WebServer 的路由。
二、注解路由概述
Voovan 注解路由说明:
- 支持通过注解形式注册 Http 请求路由
类上和方法上的路由注解如果没有指定一个路由路径,则默认采用 /类/方法
的方式拼装出一个默认路由,路由请求的方法如果没有指定,则默认为GET 方法
, 如果路由注解在方法上没有指定 HTTP 请求的方法,则默认使用类上指定的 HTTP 请求方法,如果方法上指定了,则忽略类上指定的 HTTP 方法,使用指定的方法.
- 框架会自动将您方法中的参数映射成为一个带路径参数路由.
如:public String methodA(@param("param1")String mm)
会自动映射出/className/methodA
这种基本路由 和 /className/methodA/:param1
这种带路径参数的路由。
- 支持通过注解获取
请求参数
,Cookie参数
,请求头
,请求报文
,会话参数
- 如果代码中的方法的参数中有 HttpRequest, HttpResponse, HttpSession 类型的参数则会自动选取当前请求的这三个对象实例作为参数.
- 如果代码中没有对方法的参数进行注解,则框架会默认根据请求参数的顺序,将请求参数按顺序映射成方法参数。
- 代码中的方法被响应的路由触发后的返回值的处理有几个约定:
- 如果返回类型为 基本类型 或者 String,则直接发送。
- 如果返回类型为 byte[],则直接发送。
- 如果返回类型为 复杂对象,则转换为 JSON 字符串的形式发送。
注解概述
@Router
路由注解注解点:
类 、 方法path/value:
路悠的锚点method:
http请求的方法类型singleton:
true: 单例模式的路由,每次都会使用路由注册时的实例, false: 每次都会创建新的实例用于路由处理。
singleton这个属性只在类的 @Router 注解上生效, 在方法上不会产生任何效果。
单例模式被注解的类只会在注册路由时创建一个实例,这个类下的所有带有注解路由的方法都会使用这个实例来执行。
@Param
请求参数注解注解点:
方法的参数name:
提取请求参数的名称@Head
请求头注解注解点:
方法的参数name:
提取请求头的的名称@Cookie
Cookie 注解注解点:
方法的参数name:
提取 Cookie 参数的名称@Body
请求报文注解注解点:
方法的参数@Session
会话注解注解点:
方法的参数name:
提取 Session 参数的名称
相信熟悉Spring MVC 的同学看完上面注解已经知道如何使用.不熟悉的同学可以对照一下的例子和其中的舒适加强理解。
三、注解样例
类: org.voovan.test.http.router.AnnotationRouterTest
注意: 由于在配置中我们指定了扫描的包路径为:org.voovan.test.http.router所以这个类是可以被扫描到的.
package org.voovan.test.http.router;
import org.voovan.http.server.HttpRequest;
import org.voovan.http.server.HttpResponse;
import org.voovan.http.server.HttpSession;
import org.voovan.http.server.module.annontationRouter.annotation.*;
//将当前类注解为一个请求路由处理类, 采用默认的请求方法 GET
//为当前类指定一个请求路径为:/annon,如果不指定则默认的路径为/AnnotationRouterTest
@Router("/annon")
public class AnnotationRouterTest {
//将当前方法注解为一个请求路由
//当前方法的请求路由为:/annon/index,采用方法名作为路由的路径
@Router
public String index(){
return "index";
}
//将当前方法注解为一个请求路由
//当前方法的请求路由为:/annon/params,采用方法名作为路由的路径
//将请求中名为 aa 的 参数在调用时注入成方法的 aa 参数
//将请求中名为 bb 的 参数在调用时注入成方法的 bb 参数
@Router
public String params(@Param("bb") String aa, @Param("aa") int bb){
return "params: aa=" + aa + ", bb=" + bb;
}
//将当前方法注解为一个请求路由
//当前方法的请求路由为:/annon/cookie,采用方法名作为路由的路径
//将Cookie中名为 _ga 的 参数在调用时注入成方法的 aa 参数
//同时将请求对象,响应对象和会话对象在调用时注入到方法的参数
@Router
public String cookie(@Cookie("_ga") String aa, HttpRequest request, HttpResponse response, HttpSession session){
return "cookie: " + aa + " " +request +" " +response +" " +session ;
}
//将当前方法注解为一个请求路由
//当前方法的请求路由为:/annon/head,采用方法名作为路由的路径
//将head中名为 Connection 的属性在调用时注入成方法的 aa 参数
@Router
public String head(@Head("Connection") String aa){
return "head: " + aa;
}
//将当前方法注解为一个请求路由, 并指定请求的方法为 POST,在这里 POST 会覆盖类注解的请求方法 GET
//当前方法的请求路由为:/annon/body,采用方法名作为路由的路径
//将请求中报文在调用时注入成方法的 aa 参数,在 resetful 中经常被使用到
@Router(method="POST")
public String body(@Body String aa){
return "body: " + aa;
}
//将当前方法注解为一个请求路由, 并指定请求的访问路径为 sp
//当前方法的请求路由为:/annon/sp
//将请求中报文在调用时的参数按照顺序在调用方法时注入成方法的参数
@Router("/sp")
public String seqparams(String aa, int bb){
return "seqparams: param1=" + aa + ", param2=" + bb;
}
}
以上的代码已经同步到GIT@OSC 和 github, 有需要的同学可以clone并运行org.voovan.test.http.WebServerDemo
类进行测试