首页 > Java > java教程 > 正文

Spring Validation:基于抽象请求参数类的灵活校验方案

花韻仙語
发布: 2025-10-12 11:11:00
原创
212人浏览过

spring validation:基于抽象请求参数类的灵活校验方案

本文旨在解决Spring Boot项目中,如何针对不同类型的报告生成需求,设计可扩展且易于维护的请求参数校验方案。通过抽象父类定义通用参数,子类继承并添加特定参数,结合Spring Validation框架,实现灵活的请求参数校验,避免代码冗余,提高代码复用率。

在实际的Spring Boot项目中,我们经常会遇到需要根据不同的请求参数生成不同类型的报告的场景。例如,一个报告生成接口可能需要根据category参数来决定生成哪种类型的报告,而不同类型的报告可能需要不同的请求参数。如何设计一个可扩展且易于维护的请求参数校验方案,就显得尤为重要。

一种常见的做法是定义一个抽象的请求参数类,其中包含所有报告类型都需要的通用参数,然后为每种报告类型定义一个具体的请求参数类,继承自抽象类,并添加该报告类型特有的参数。

1. 定义抽象请求参数类

首先,定义一个抽象类 ReportRequestDTO,其中包含所有报告类型都需要的通用参数,并使用JSR-303注解进行校验。

import lombok.Data;
import javax.validation.constraints.NotEmpty;

@Data
public abstract class ReportRequestDTO  {
    @NotEmpty(message = "foo不能为空")
    private String foo;

    @NotEmpty(message = "bar不能为空")
    private String bar;
}
登录后复制

在这个例子中,foo 和 bar 是所有报告类型都需要的通用参数,@NotEmpty 注解表示这两个参数不能为空。message属性可以自定义校验失败时的提示信息。

2. 定义具体请求参数类

接下来,为每种报告类型定义一个具体的请求参数类,继承自 ReportRequestDTO,并添加该报告类型特有的参数,同样使用JSR-303注解进行校验。

import lombok.Data;
import javax.validation.constraints.NotEmpty;

@Data
public class ReportADTO extends ReportRequestDTO  {
    @NotEmpty(message = "foobar不能为空")
    private String foobar;
}
登录后复制
import lombok.Data;

@Data
public class ReportBDTO extends ReportRequestDTO {
    private Integer someNumber;
}
登录后复制

ReportADTO 继承了 ReportRequestDTO,并添加了 foobar 参数,这个参数是 ReportA 特有的。ReportBDTO 继承了 ReportRequestDTO,并添加了 someNumber 参数,这个参数是 ReportB 特有的。

3. 在Controller中使用Validation

百度智能云·曦灵
百度智能云·曦灵

百度旗下的AI数字人平台

百度智能云·曦灵 83
查看详情 百度智能云·曦灵

在 Controller 中,接收请求参数,并使用 @Valid 注解进行校验。关键在于如何根据category参数实例化对应的DTO。

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import org.springframework.web.server.ResponseStatusException;

@RestController
@Validated // 需要添加此注解才能使@Valid生效
public class ReportController {

    @GetMapping("/report")
    @ResponseBody
    public ResponseEntity<String> getReport(
            @RequestParam(value = "category") String category,
            @Valid @ModelAttribute ReportRequestDTO reportRequestDTO) {

        if ("A".equals(category)) {
            if (!(reportRequestDTO instanceof ReportADTO)) {
                 throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "category A requires ReportADTO");
            }
            ReportADTO reportADTO = (ReportADTO) reportRequestDTO;
            // Process ReportA
            return ResponseEntity.ok("Report A generated with foo: " + reportADTO.getFoo() + ", bar: " + reportADTO.getBar() + ", foobar: " + reportADTO.getFoobar());
        } else if ("B".equals(category)) {
            if (!(reportRequestDTO instanceof ReportBDTO)) {
                throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "category B requires ReportBDTO");
            }
            ReportBDTO reportBDTO = (ReportBDTO) reportRequestDTO;
            // Process ReportB
            return ResponseEntity.ok("Report B generated with foo: " + reportBDTO.getFoo() + ", bar: " + reportBDTO.getBar() + ", someNumber: " + reportBDTO.getSomeNumber());
        } else {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid category");
        }
    }
}
登录后复制

在这个例子中,我们使用了 @Valid 注解来校验 ReportRequestDTO 对象。如果校验失败,Spring Boot 会自动抛出一个 MethodArgumentNotValidException 异常。

重要提示:

  • @Validated 注解: Controller类需要添加@Validated注解,才能使@Valid注解生效。
  • 类型转换: 在Controller方法中,需要根据category参数,将ReportRequestDTO转换为对应的具体类型。
  • 异常处理: 需要处理MethodArgumentNotValidException异常,并返回合适的错误信息。可以使用@ExceptionHandler注解来定义全局异常处理。
  • DTO实例化: 由于无法直接通过new关键字实例化抽象类,需要借助其他方式,例如反射、工厂模式等,根据category参数动态创建对应的DTO实例。 本例中,直接使用了 @ModelAttribute,Spring会自动根据请求参数进行绑定,但需要确保请求参数的名称与DTO的属性名称一致。
  • ModelAttribute绑定: @ModelAttribute 注解会将请求参数绑定到 ReportRequestDTO 对象上。 如果请求参数中包含了 ReportADTO 或 ReportBDTO 特有的参数,Spring 会尝试将这些参数也绑定到 ReportRequestDTO 对象上,但由于 ReportRequestDTO 类中没有这些属性,这些参数会被忽略。因此,需要在Controller方法中进行类型转换,才能访问到这些参数。

4. 全局异常处理

为了更好地处理校验失败的情况,可以定义一个全局异常处理类,处理 MethodArgumentNotValidException 异常,并返回统一的错误信息。

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Object> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getFieldErrors().forEach(error -> {
            errors.put(error.getField(), error.getDefaultMessage());
        });
        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
    }
}
登录后复制

总结

通过定义抽象请求参数类和具体请求参数类,结合Spring Validation框架,我们可以实现一个可扩展且易于维护的请求参数校验方案。这种方案可以避免代码冗余,提高代码复用率,并使代码更加清晰易懂。同时,全局异常处理可以提供统一的错误信息,提高用户体验。

注意事项

  • 在实际项目中,可以根据需要添加更多的校验注解,例如 @Size、@Email、@Pattern 等。
  • 可以使用自定义的校验注解,实现更复杂的校验逻辑。
  • 可以结合AOP,实现更加灵活的校验方案。
  • 务必进行充分的测试,确保校验逻辑的正确性。

这种方法允许你在不修改现有端点的情况下添加新的报告类型,只需创建新的DTO类并实现相应的报告生成逻辑即可,提高了代码的可维护性和可扩展性。

以上就是Spring Validation:基于抽象请求参数类的灵活校验方案的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号