Repository navigation
Route
Route是festival-web核心功能之一,在编写Web服务的时候,首先需要的就是声明一个路由。路由本身是一个由@RouteController注解标注的一个类,一个类一旦被@RouteController注解标注,那么便可以将Web请求映射到其拥有的方法上。
为了将请求映射到路由类的方法上,可以在路由类的方法上使用@RouteMapping注解来声明一个请求映射。使用@RouteMapping声明一个映射方法时,必须传入一个映射地址以及相应的Http请求方法。以下代码展示了@RouteMapping的使用方式。
@Singleton
@RouteController
public class HelloController {
//hello方法最终的请求路径是/hello
@RouteMapping(value = "/hello",method = HttpMethod.GET)
public String hello() {
return "hello festival";
}
}除了定义映射方法之外,@RouteMapping也可以注解在路由类上,表示父路径,注解在路由类上的@RouteMapping不需要设置请求方法。使用方式如下:
@Singleton
@RouteMapping("/parent")
@RouteController
public class HelloController {
//hello方法最终的请求路径是/parent/hello
@RouteMapping(value = "/hello",method = HttpMethod.GET)
public String hello() {
return "hello festival";
}
}映射方法的返回值会返回给前端,对于复杂对象会以json的形式返回。如果方法没有返回值,则需要用户自行处理请求的响应,这需要用户获取请求的上下文RoutingContext来实现。
使用@RouteMapping可以声明一个映射方法,但每次都需要指定请求方式,未免太过麻烦,且不利于编写rest风格的路由。为了解决这个问题,可以使用@RouteMapping的子注解@GetMapping、@PostMapping、@PutMapping、@DeleteMapping。这4类注解分别对应了Http的4种请求,使用方式如下:
@Singleton
@RouteController
public class UserController {
@GetMapping("/hello")
public String hello() {
return "hello festival";
}
@PostMapping("/hello")
public String hello() {
return "hello festival";
}
@PutMapping("/hello")
public String hello() {
return "hello festival";
}
@DeleteMapping("/hello")
public String hello() {
return "hello festival";
}
}WebServer对于每一个请求,都会创建一个RoutingContext,代表请求的上下文,通过RoutingContext可以获取所有的请求数据以及对请求作出一些响应,具体可以参考Vertx-Web的相关问题。RoutingContext的获取,可以通过在路由方法上声明一个RoutingContext来实现,RoutingContext的实例将自动注入到方法上。
@GetMapping("/testContext")
public void test(RoutingContext routingContext) {
...
}获取了RoutingContext之后,可以通过RoutingContext对Http请求和响应做多种操作:
- 获取请求参数
MultiMap queryParams = routingContext.queryParams();
- 获取HTTP请求对象及其数据
HttpServerRequest request = routingContext.request(); MultiMap formAttributes = request.formAttributes(); MultiMap headers = request.headers(); String path = request.path(); HttpConnection connection = request.connection();
- 文件上传
for (FileUpload fileUpload : routingContext.fileUploads()) { ... }
- 获取并设置HTTP响应对象
routingContext.response() .putHeader("content-type", "text/plain") .end("Hello World from Vert.x-Web!");
更多RoutingContext用法请参考RoutingContext文档、HttpServerRequest文档[HttpServerResponse文档]、(https://vertx.io/docs/apidocs/io/vertx/reactivex/core/http/HttpServerResponse.html)。
如果想要直接获取Router对象来配置路由,可以定义一个可被容器扫描的Bean类并且实现RouterAware接口,WebContext在处理此类bean的时候会通过调用此bean的setRouter(Router router)方法将webServer的Router对象传入这个bean,拿到Router对象后,我们可以对路由进行个性化配置。配置方法详见vertx中关于Router和Route的介绍及Router API文档和Route API文档。
Example:
@Named
public class RouterConfiguration implements RouterAware {
Router router;
@Override
public void setRouter(Router router) throws BeansException {
this.router = router;
router.route(HttpMethod.GET, "/costom").handler(routingContext -> {
routingContext.response().end("Hello");
});
}
}访问 http://localhost:8083/costom 获得结果Hello。
除了直接获取Router对象来添加自定义路由的方式之外,还可以通过向容器注入RouteAttribute实例来添加自定义路由,这也是推荐的方式。通过注入RouteAttribute添加的路由,可以被Filter拦截。使用方式如下:
@Singleton
@Named("route1")
public RouteAttribute customRoute() {
return RouteAttribute.builder()
.httpMethod(HttpMethod.GET)
.url("/custom")
.contextHandler(routingContext -> {
routingContext.response().end("test custom!");
})
.build();
}festival框架提供对几种模板引擎的支持,包括Jade、Freemarker、Thymeleaf。有关这三种模板引擎的写法请查阅官方文档。
要想在框架中启用模板引擎,您需要在application.yaml中设置:
server:
template:
enable: true或者在application.properties中设置:
server.template.enable = true在配置文件中,template有如下属性:
- enable:是否启用模板引擎。
- type:设置模板引擎类型,可以设置的属性有"freemarker"、"thymeleaf"、"jade"。(必选)
- cache.enable:设置是否启用缓存,默认为开。
- path:设置读取模板引擎路径,默认为“src/main/resources/template”。
- suffix:设置模板引擎文件后缀。(必选)
ModelAndView通常在controller中,作为返回值使用,于向客户端返回模型和视图。
ModelAndView有如下两个构造方法:
- ModelAndView(String view):
- view:指定模板引擎的文件名称(不包括文件名后缀)
- ModelAndView(String view, Map<String, Object> model):
- view:指定模板引擎的文件名称(不包括文件名后缀)
- model:为ModelAndView设置model
使用add()方法可以为model添加属性。
下面是一个使用ModelAndView的例子:
@Singleton
@RouteController
public class example{
@GetMapping("/modelandview")
public ModelAndView exampleModelAndView() {
ModelAndView modelAndView = new ModelAndView("template");
modelAndView.add("hello", "hello modelandview");
return modelAndView;
}
}要使用Thymeleaf,您需要在项目中添加以下依赖项: io.vertx:vertx-web-templ-thymeleaf:${version}。
Thymeleaf可以直接使用ModelAndView中model的属性。
下面是一个例子:
<p th:text="${hello}"></p>我们将看到:
hello modelandview
要使用FreeMarker,您需要在项目中添加以下依赖项: io.vertx:vertx-web-templ-freemarker:${version}
FreeMarker可以直接使用ModelAndView中model的属性。
下面是一个例子:
${hello}我们将看到:
hello modelandview
要使用Jade,您需要在项目中添加以下依赖项: io.vertx:vertx-web-templ-jade: ${version}
Jade可以直接使用ModelAndView中model的属性。
下面是一个例子:
div !{hello}我们将看到:
hello modelandview