如何根据另一字段取值动态修改@Schema注解且不使用Java继承
Java注解本身是静态元数据,无法在运行时根据对象的字段值动态调整注解属性,因此不存在直接修改@Schema属性值的原生实现,但可以通过以下无需继承的方案同时满足业务校验、接口文档说明的需求:
方案1:JSR-380自定义跨字段校验 + 文档说明
这是兼容性最强、实现最简单的方案,同时覆盖实际参数校验和接口文档规则说明:
- 自定义跨字段校验注解
@Target({TYPE}) @Retention(RUNTIME) @Constraint(validatedBy = MailingRuleValidator.class) public @interface MailingValid { String message() default "渠道类型为EMAIL时mailing字段不能为空"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
- 实现校验逻辑
public class MailingRuleValidator implements ConstraintValidator<MailingValid, Response> { @Override public boolean isValid(Response response, ConstraintValidatorContext context) { // 渠道为EMAIL时校验mailing非空,其他场景直接通过 return ChannelType.EMAIL != response.getType() || response.getMailing() != null; } }
- 给原Response类添加校验注解,同时补充
@Schema的规则说明
@Getter @Setter @MailingValid // 新增自定义校验 public class Response { @Schema(required = true) private Long id; @Schema(required = true, enumAsRef = true) private ChannelType type; @Schema(required = true, nullable = true, description = "当type取值为EMAIL时该字段不可为空,其余场景允许为null") private Mailing mailing; // ... }
方案2:SpringDoc OpenAPI 动态Schema配置
如果使用SpringDoc 2.x版本,可以通过OpenAPI自定义配置实现文档层面的动态规则展示,配合方案1的校验逻辑即可完全匹配需求:
在接口方法上通过@ApiResponse指定动态Schema规则,示例如下:
@GetMapping("/test") @ApiResponse(responseCode = "200", content = @Content( schema = @Schema(implementation = Response.class), examples = @ExampleObject(value = "{\"type\":\"EMAIL\",\"mailing\":{}}") )) public Response test() { // 业务逻辑 }
内容的提问来源于stack exchange,提问作者Алексеев станислав
相关产品推荐
相关产品推荐

