Skip to content

注解使用

本节集中讲三个注解:@APIVersion、@RawResponse、@MyApiResponse。

注解归属说明

这三个注解定义在 forge-processor 模块,但实际是在 forge-core 的请求处理链路里生效。引入 forge-core 后会自动传递依赖,不需要手工再引 processor。

@APIVersion:注解驱动的版本路由

把 @APIVersion 标在方法或类上,路由会自动加上 /v1/v2 这样的版本前缀。

java
import cn.cvking.forge.processor.annotation.APIVersion;
import cn.cvking.forge.processor.enmu.APIVersionEnum;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
public class UserController {

    @APIVersion(APIVersionEnum.V1)
    @GetMapping("/{id}")
    public String getUserV1(@PathVariable Long id) {
        return "v1 result: " + id;
    }

    @APIVersion(APIVersionEnum.V2)
    @GetMapping("/{id}")
    public Object getUserV2(@PathVariable Long id) {
        return java.util.Map.of("id", id, "name", "张三");
    }
}

实际生效的路由分别是 GET /v1/user/{id}GET /v2/user/{id},Spring MVC 把它们识别为两个完全独立的端点,可以共存。

也可以把 @APIVersion 标在类上,整个类下所有方法共享一个版本前缀;方法上单独标的会优先于类上的注解。

想新增 V3 怎么办

APIVersionEnum 枚举里加一行 V3("/v3", "v3") 即可,不需要改其它代码。原理见 设计文档 · 版本路由

@RawResponse:跳过统一包装

某些接口不希望响应被包装成 Result,典型场景:

  • 返回二进制流(文件下载)
  • 对接固定格式的第三方约定(例如微信回调)
  • Server-Sent Events 流式输出

在方法或类上加 @RawResponse:

java
@GetMapping("/raw")
@RawResponse
public String raw() {
    return "我会直接返回,不会被 Result 包裹";
}

@RawResponse 同样可以标在类上,整个类下所有方法都不会被包装。

@MyApiResponse:自定义包装的状态码与消息

如果想覆盖默认的 200 与「操作成功」,用 @MyApiResponse 显式指定:

java
@PostMapping
@MyApiResponse(httpCode = 201, code = 2010, msg = "用户创建成功")
public UserDTO create(@Valid @RequestBody UserDTO dto) {
    return userService.create(dto);
}

返回体仍然是 Result 结构,但 code 与 message 用你指定的值,HTTP 状态码也按 httpCode 写入响应头。

参数默认值含义
httpCode200HTTP 响应状态码
code200业务状态码,写入 Result.code
msg"操作成功"业务消息,写入 Result.message

互斥规则

@RawResponse 与 @MyApiResponse 不能同时标在同一个元素上:前者表示「我不要包装」,后者表示「我要定制包装」,语义冲突。框架在编译期就会拦下这种用法:

[ERROR] /path/to/Controller.java:[42,5]
        Semantic Error: @MyApiResponse and @RawResponse cannot be used on the same element.

这是由 forge-processor 模块的编译期处理器完成的,详见 设计文档 · 编译期互斥校验