Skip to content

Controller 开发

This content is not available in your language yet.

Feat Cloud 在设计 Controller 注解时,一定程度上延用了 Spring 的设计理念,使得用户更容易理解和运用。

当然,我们也并非完全复刻 Spring 的 Controller 注解,而是进行了极致的简化,剔除了不必要的灵活性。

相关注解:

  • tech.smartboot.feat.cloud.annotation.Controller
  • tech.smartboot.feat.cloud.annotation.RequestMapping
  • tech.smartboot.feat.cloud.annotation.Param
  • tech.smartboot.feat.cloud.annotation.PathParam
  • tech.smartboot.feat.cloud.annotation.InterceptorMapping

@Controller 用于标记一个类为控制器,作为 Spring 风格的注解设计,降低学习成本。

通常与 @RequestMapping 一起使用来定义请求映射路径。

定义:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
@Documented
public @interface Controller {
String value() default "";
}

value 参数说明:

  • value() 定义了 Controller 的基础路径,其他方法级别的请求路径会基于这个基础路径。
  • 默认情况下,value 是一个空字符串,意味着没有基础路径前缀。
  • 示例:如果设置 @Controller("/user"),那么该 Controller 下的所有方法将通过 /user 路径前缀访问。

@RequestMapping 用于标记方法,表示该方法处理特定的 HTTP 请求路径。

支持指定HTTP请求方法,有效类型:GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE 定义:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
@Documented
public @interface RequestMapping {
String value() default "";
RequestMethod[] method() default {};
}

参数说明:

  • value: 指定与该方法关联的 URL 路径,默认为空字符串,意味着使用 Controller 级别的路径前缀(如果有)。
  • method: 指定该方法支持的 HTTP 请求类型,默认不限制请求方法,即所有类型都可以访问该方法。

@Param 用于绑定请求中的查询参数(Query Parameters)到方法参数上。当方法参数为自定义POJO类型时,可无需使用@Param注解,框架会自动进行参数绑定。

定义:

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.SOURCE)
@Documented
public @interface Param {
/**
* 指定要绑定的查询参数的名称。
*
* @return 参数名称
*/
String value();
}

value 参数说明:

  • 如果 HTTP 请求中没有与 value 匹配的查询参数,则方法参数将被赋予默认值(如 null、0 或 false,取决于类型)。
  • 示例:若方法定义为 @Param("id") int userId,则会尝试从请求中获取名为 id 的参数并转换为整数赋值给 userId

@PathParam 用于绑定请求中的路径参数(Path Parameters)到方法参数上。

定义:

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.SOURCE)
@Documented
public @interface PathParam {
/**
* 参数名称
*
* @return 参数名称
*/
String value();
}

value 参数说明: 指定要绑定的路径参数的名称,该名称必须与路由中定义的占位符名称一致。

  • 示例:若 URL 定义为 /user/{id},则应使用 @PathParam("id") 来绑定路径中的 id 值到方法参数。
  • 如果 HTTP 请求路径中没有匹配的参数名,则框架会抛出异常或自动赋予默认值(如 null、0 等),具体行为取决于框架实现和参数类型。

@InterceptorMapping 用于为特定的请求路径添加拦截器逻辑,在请求到达目标方法之前执行一些操作。

定义:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
@Documented
public @interface InterceptorMapping {
String[] value() default "";
}

value 参数说明: 指定拦截器应用的 URL 路径模式数组。

  • 支持精确匹配(如 /path)和通配符匹配(如 /path/*)。
  • 如果未指定,默认为空数组,表示拦截器不匹配任何请求。
  • 示例:若设置 @InterceptorMapping({"/user", "/api/*"}),则该拦截器会作用于所有 /user/api 下的请求路径。

创建一个简单的 Controller 示例:

@Controller("userApi")
public class UserController {
// 支持路径参数
@RequestMapping("/users/:id")
public String getUser(@PathParam("id") String id) {
return "User: " + id;
}
// 支持查询参数
@RequestMapping("/users/search")
public String searchUsers(@Param("name") String name, @Param("age") int age) {
return "Search users with name: " + name + ", age: " + age;
}
// 支持对象参数绑定
@RequestMapping("/users/create")
public RestResult<Map<String, String>> createUser(UserParam param) {
RestResult<Map<String, String>> result = new RestResult<>();
result.setData(Collections.singletonMap("id", "123"));
return result;
}
}

通过 @InterceptorMapping 注解可以为 Controller 添加拦截器,以实现请求的预处理或后处理逻辑。

// 为用户API添加拦截器
@InterceptorMapping({"/users/*"})
public Interceptor userApiInterceptor() {
return (context, completableFuture, chain) -> {
System.out.println("Intercepting user API request...");
// 可以在请求处理前执行前置逻辑
// 继续执行请求链
chain.proceed(context, completableFuture);
// 可以在请求处理后执行后置逻辑
System.out.println("Finished intercepting user API request.");
};
}

说明与注意事项:

  • 拦截路径匹配@InterceptorMappingvalue 属性用于指定拦截器生效的路径模式,支持精确匹配(如 /user)和通配符匹配(如 /user/*)。
  • 拦截器顺序:多个拦截器按照定义顺序依次执行,形成拦截器链。
  • 异步处理:由于 HTTP 请求处理可能是异步的,因此拦截器中应正确处理 CompletableFuture
  • 避免阻塞:拦截器中的逻辑不应长时间阻塞主线程,建议将耗时操作提交到独立线程池。
  • 异常处理:拦截器内部需要自行捕获并处理异常,防止因未处理异常导致请求失败。

与 Spring Boot 相比,Feat Cloud 的注解处理方式有本质区别:

特性Feat CloudSpring Boot
注解处理时机编译期运行时
反射使用不需要需要
性能更高相对较低
灵活性简洁高效更加灵活

这种设计使得 Feat Cloud 在保持类似 Spring Boot 开发体验的同时,实现了更好的性能表现。