
本文旨在介绍如何在Spring Boot项目中,利用抽象类和继承机制,结合`javax.validation`框架,实现灵活且可扩展的请求参数验证方案。通过定义抽象的请求参数类,并让具体的请求参数类继承它,我们可以实现公共参数的统一验证,并针对不同的业务场景进行定制化的参数验证。
在实际的Web应用开发中,经常会遇到需要根据不同的业务场景,对请求参数进行不同验证的情况。如果将所有的验证逻辑都写在一个Controller方法中,会导致代码臃肿、难以维护。本文将介绍一种利用抽象类和继承机制,结合Spring Validation框架,实现灵活的请求参数验证方案。
方案概述
该方案的核心思想是:
定义一个抽象的请求参数类,包含所有请求中可能出现的公共参数,并使用javax.validation注解对这些参数进行验证。针对不同的业务场景,创建具体的请求参数类,继承自抽象的请求参数类,并添加该场景特有的参数,同样使用javax.validation注解进行验证。在Controller方法中,接收抽象的请求参数类作为参数,Spring会自动根据请求参数,实例化对应的具体请求参数类,并进行验证。通过javax.validation.Validator接口,手动触发验证,并处理验证结果。
具体实现
1. 定义抽象请求参数类
import lombok.Data;import javax.validation.constraints.NotEmpty;@Datapublic abstract class ReportRequestDTO { @NotEmpty(message = "foo不能为空") private String foo; @NotEmpty(message = "bar不能为空") private String bar;}
在这个例子中,ReportRequestDTO是一个抽象类,包含了两个公共参数foo和bar,并使用@NotEmpty注解,表示这两个参数不能为空。message属性用于自定义验证失败时的错误信息。
2. 定义具体请求参数类
import lombok.Data;import javax.validation.constraints.NotEmpty;@Datapublic class ReportADTO extends ReportRequestDTO { @NotEmpty(message = "foobar不能为空") private String foobar;}
ReportADTO继承自ReportRequestDTO,并添加了一个特有的参数foobar,同样使用@NotEmpty注解进行验证。
3. Controller方法
import org.springframework.http.ResponseEntity;import org.springframework.validation.annotation.Validated;import org.springframework.web.bind.annotation.*;import javax.validation.Valid;import javax.validation.Validator;import org.springframework.beans.factory.annotation.Autowired;import javax.validation.ConstraintViolation;import java.util.Set;import org.springframework.http.HttpStatus;import org.springframework.web.server.ResponseStatusException;@RestController@RequestMapping("/reports")@Validatedpublic class ReportController { @Autowired private Validator validator; @GetMapping @ResponseBody public ResponseEntity getReport(@RequestParam(value = "category") String category, @Valid ReportRequestDTO reportRequestDTO) { if ("A".equals(category)) { ReportADTO reportADTO = new ReportADTO(); reportADTO.setFoo(reportRequestDTO.getFoo()); reportADTO.setBar(reportRequestDTO.getBar()); // simulate set parameter from request reportADTO.setFoobar("test"); Set<ConstraintViolation> violations = validator.validate(reportADTO); if (!violations.isEmpty()) { StringBuilder sb = new StringBuilder(); for (ConstraintViolation violation : violations) { sb.append(violation.getMessage()).append(";"); } throw new ResponseStatusException(HttpStatus.BAD_REQUEST, sb.toString()); } return ResponseEntity.ok("Report A generated with: " + reportADTO.toString()); } else { return ResponseEntity.ok("Other report"); } }}
在这个例子中,getReport方法接收一个ReportRequestDTO类型的参数reportRequestDTO。Spring会自动根据请求参数,尝试实例化ReportADTO或其他的ReportRequestDTO子类。
注意: 这里使用 javax.validation.Validator 手动触发验证。首先,需要注入Validator接口。然后,根据不同的category,手动创建对应的DTO对象,并将请求中的公共参数设置到该对象中。最后,调用validator.validate()方法进行验证,并处理验证结果。 如果验证失败,将错误信息封装到ResponseStatusException中,并抛出,Spring会自动处理该异常,并返回相应的错误信息。
4. 全局异常处理
为了统一处理验证失败的异常,可以自定义一个全局异常处理类。
import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.server.ResponseStatusException;@ControllerAdvicepublic class GlobalExceptionHandler { @ExceptionHandler(ResponseStatusException.class) public ResponseEntity handleValidationException(ResponseStatusException ex) { return new ResponseEntity(ex.getReason(), ex.getStatus()); }}
总结
通过以上步骤,我们实现了一个灵活且可扩展的请求参数验证方案。该方案的优点包括:
代码复用性高:公共参数的验证逻辑只需要定义一次,可以在多个具体的请求参数类中复用。可扩展性强:当需要添加新的业务场景时,只需要创建新的请求参数类,并继承自抽象的请求参数类即可。易于维护:每个请求参数类的验证逻辑都集中在该类中,易于理解和维护。
注意事项:
确保Spring Validation框架已正确配置。@Valid注解用于触发验证,需要添加到需要验证的参数上。javax.validation.Validator接口提供了手动触发验证的功能,可以灵活地控制验证的时机和方式。全局异常处理可以统一处理验证失败的异常,并返回友好的错误信息。在实际应用中,可以根据需要,自定义更多的验证注解,以满足不同的业务需求。
以上就是Spring Validation:利用抽象请求参数类实现灵活的参数验证的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/14814.html
微信扫一扫
支付宝扫一扫