使用注解

Cloudopt Next 中的路由是通过注解来使用的,任意类继承 Resource 类并在头部增加 @API 即可。如:

  1. @API("/")
  2. class IndexController : Resource() {
  3. @GET
  4. fun get(){
  5. renderText("Hello World!")
  6. }
  7. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @GET
  4. public void get(){
  5. renderText("Hello World!");
  6. }
  7. }

@API

Cloudopt Next在启动时会自动扫描含有@API注解的类,并自动解析这个类里面的所有的方法。

@API中可以设置具体的URL,这个类中的方法也将自动继承。

如:

@API(“/“) => http://localhost:8080/

@API(“/test”) => http://localhost:8080/test

RESTful

Cloudopt Next支持 @GET、@POST、@PUT、@DELETE、@PATCH 五种注解,分别对应 HTTP 请求中的五种 method。RESTful 相关的注解只能使用在方法上,与 @API 一样是支持配置 URL 的。Cloudopt Next 会将@API 中配置的 URL 与 RESTful 注解中配置的 URL 自动拼接到一起。

如:

  1. @API("/")
  2. class IndexController : Resource() {
  3. @GET("hello")
  4. fun get(){
  5. renderText("Hello World!")
  6. }
  7. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @GET("hello")
  4. public void get(){
  5. renderText("Hello World!");
  6. }
  7. }

您将需要通过 GET http://localhost:8080/hello 进行访问。

获取参数

如果您需要获取客户端传递过来的参数,您可以直接在方法中使用 getParam() 方法获取。

  1. @API("/")
  2. class IndexController : Resource() {
  3. @GET
  4. fun get(){
  5. renderText(getParam("name") ?: "")
  6. }
  7. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @GET
  4. public void get(){
  5. renderText(getParam("name"));
  6. }
  7. }

获取URL参数

如果您需要获取URL上的参数,需要在RESTful注解中设置:参数名。

  1. @API("/")
  2. class IndexController : Resource() {
  3. @GET("/:name")
  4. fun get(){
  5. renderText(getParam("name") ?: "")
  6. }
  7. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @GET("/:name")
  4. public void get(){
  5. renderText(getParam("name"));
  6. }
  7. }

获取表单数据

如果您需要获取客户端传递过来的参数,您可以直接在方法中使用getParam()方法获取。

  1. @API("/")
  2. class IndexController : Resource() {
  3. @GET
  4. fun get(){
  5. renderText(getParam("name") ?: "")
  6. renderJson(getParam(TestBean::class.java))
  7. }
  8. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @GET
  4. public void get(){
  5. renderText(getAttr("name"));
  6. renderJson(getAttr(TestBean::class.java));
  7. }
  8. }

传递上下文

有些情况下,可能需要将一个对象在上下文中进行传递,比如说在验证器中已经查询过数据库了,那么查询结果下一层还需要继续用的话,可以直接往下传递。

路由层是直接继承 Resource 的,所以可以直接将 context 上下文对象取出进行操作。

  1. context.data()["key"] = "value"

取出传递的内容同样调用 data() 然后指定 key 即可。

  1. val key = context.data()["key"]

Cookie

Cookie还支持更多设置,具体可以看setCookie方法的参数注释。

  1. @API("/")
  2. class IndexController : Resource() {
  3. @GET
  4. fun get(){
  5. setCookie("key","value")
  6. getCookie("key")
  7. delCookie("key")
  8. }
  9. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @GET
  4. public void get(){
  5. setCookie("key","value");
  6. getCookie("key");
  7. delCookie("key");
  8. }
  9. }

HTTP Header

  1. @API("/")
  2. class IndexController : Resource() {
  3. @GET
  4. fun get(){
  5. setHeader("key","value")
  6. getHeader("key")
  7. }
  8. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @GET
  4. public void get(){
  5. setHeader("key","value");
  6. getHeader("key");
  7. }
  8. }

获取IP

  1. @API("/")
  2. class IndexController : Resource() {
  3. @GET
  4. fun get(){
  5. getIp()
  6. }
  7. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @GET
  4. public void get(){
  5. getIp();
  6. }
  7. }

获取客户端支持的语言

  1. @API("/")
  2. class IndexController : Resource() {
  3. @GET
  4. fun get(){
  5. lang()
  6. }
  7. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @GET
  4. public void get(){
  5. lang();
  6. }
  7. }

获取Body

Cloudopt Next 支持自动将Body转为JSON或者JSONArray,使用内置的Jsoner进行转换。建议在使用Cloudopt Next期间处理JSON都通过Jsoner工具类。具体见Json一章。同时还支持获取到Json字符串后自动反序列化为对象。

  1. @API("/")
  2. class IndexController : Resource() {
  3. @GET
  4. fun get(){
  5. getBody()
  6. getBodyString()
  7. getBodyJson()
  8. getBodyJson(TestBean::class.java)
  9. getBodyJsonArray()
  10. getBodyJsonArray(TestBean::class.java)
  11. }
  12. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @GET
  4. public void get(){
  5. getBody();
  6. getBodyString();
  7. getBodyJson();
  8. getBodyJson(TestBean.class);
  9. getBodyJsonArray();
  10. getBodyJsonArray(TestBean.class);
  11. }
  12. }

Render

Render系列方法是用于输出请求结果的方法,具体可见Render一章。
Render

输出文件

  1. @API("/")
  2. class IndexController : Resource() {
  3. @GET
  4. fun get(){
  5. sendFile(文件名)
  6. }
  7. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @GET
  4. public void get(){
  5. sendFile(文件名);
  6. }
  7. }

跳转

  1. @API("/")
  2. class IndexController : Resource() {
  3. @GET
  4. fun get(){
  5. redirect("/a")
  6. }
  7. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @GET
  4. public void get(){
  5. redirect("/a");
  6. }
  7. }

报错

fail方法用于强行引发HTTP请求错误,当发生HTTP请求错误时Cloudopt Next会自动调用默认的错误拦截

  1. @API("/")
  2. class IndexController : Resource() {
  3. @GET
  4. fun get(){
  5. fail(400)
  6. }
  7. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @GET
  4. public void get(){
  5. fail(400);
  6. }
  7. }

获取上传的文件

Cloudopt Next是基于vertx-web的,vertx-web在获取到用户上传的文件时会自动改名并存放,所以Cloudopt Next也延续了这个功能。当用户上传文件时,Cloudopt Next会自动改名并存放在上传文件目录,路由中能拿到的只有FileUpload对象列表。

  1. @API("/")
  2. class IndexController : Resource() {
  3. @POST
  4. fun post() {
  5. var files = getFiles()
  6. files?.forEach { file->
  7. println("-------------------------------------")
  8. println("FileName: ${file.fileName()}")
  9. println("UploadedFileName: ${file.uploadedFileName()}")
  10. println("ContentType: ${file.contentType()}")
  11. println("-------------------------------------")
  12. }
  13. renderText("success!")
  14. }
  15. }
  1. @API("/")
  2. public class IndexController extends Resource {
  3. @POST
  4. public void post(){
  5. Set<FileUpload> files = getFiles();
  6. files.forEach(file->{
  7. System.out.println("-------------------------------------");
  8. System.out.println("FileName: ${file.fileName()}");
  9. System.out.println("UploadedFileName: ${file.uploadedFileName()}");
  10. System.out.println("ContentType: ${file.contentType()}");
  11. System.out.println("-------------------------------------");
  12. });
  13. }
  14. }

参数注入

2.0.6.0-BETA 版本后支持直接声明在参数中即可。同时会根据有参方法和无参方法自动跳过参数校验,以免反射扫描降低性能。使用时请先引入 cloudopt-next-validator 插件。

  1. @GET("args")
  2. fun argsController(
  3. @Parameter("name", defaultValue = "Peter")
  4. @Chinese(false)
  5. name: String,
  6. @Parameter("age")
  7. @Min(18)
  8. age: Int
  9. ) {
  10. var map = hashMapOf<String, Any>()
  11. map["name"] = name
  12. map["age"] = age
  13. renderJson(map)
  14. }

你可以通过 @Parameter 注解指定参数名称,在用户发送 http 请求时自动将参数注入。或者使用 @RequestBody 注解将整个 body 作为 json 字符串并转为对象注入。同时还支持在参数上直接声明参数校验的注解,会自动校验参数。如果参数校验发现问题会自动发生 400 状态码错误并且将验证器上的错误信息自动放入 resource 对象中的上下文对象 context 的 data 中,可以通过自定义的错误拦截器进行拦截。

  1. val errorMessage = if(context.data().containsKey("errorMessage")){
  2. context.data()["errorMessage"].toString()
  3. }else{
  4. "This is a bad http request, please check if the parameters match the requirements."
  5. }
  6. renderJson(restult(errorStatusCode.toString(),errorMessage))

手动注册

某种情况下,可能需要手动将路由类注册到路由表中你可以在调用 NextServer.run 前手动注册进路由表。

  1. NextServer.registerResourceTable(url = HealthChecksManager.config.accessPath, HealthChecksController::class)

如果 Controller 类中是包含了 @API 注解的,那么是不需要声明 url 参数的。会自动获取 @API 中的值。

手动注册会自动将路由方法、验证器、方法拦截器等等同时注册进入。