当前位置:网站首页>数据验证框架 Apache BVal 再使用
数据验证框架 Apache BVal 再使用
2022-07-07 16:51:00 【sp42a】
关于 Apache BVal,我 N 久之前使用过,还写了甚至全网唯一的简中教程《数据验证框架 Apache BVal 简介》,我依然还是那个观点:
Apache BVal (源码)是实体数据验证 Java Bean Validation 的参考实现。Apache BVal 提供了 JSR 303 规范中所有内置 constraint 的实现,用于对 Bean 中的字段的值进行约束定义、描述和验证。若单单说 JSR 规范大渣可能还不清楚,但做过 POJO 的 Hibernate Validator 注解的朋友就知道是啥,——那为什么不使用主流的 Hibernate Validator 呢?因为这货净是个压缩包都已经 13mb 了(尽管可以有文档、源码其他在内),BVal 才只有 400 多 kb,而我只需要服务端验证而已,——天真的孩纸伤不起啊。俺的 ORM 也是 Mybatis 的,务求尽可能地轻量级。
用法
Maven 引用
添加以下两个 Maven 依赖:
<dependency>
<groupId>org.apache.bval</groupId>
<artifactId>bval-jsr</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
2.0 要求 Java 8,Apache CommonUtils 不是强依赖了,同时 JSR 验证规范也升级到 2.x。
整合 Spring
Spring 里面注入 Provider。
/** * 数据验证框架 * * @return */
@Bean
LocalValidatorFactoryBean localValidatorFactoryBean() {
LocalValidatorFactoryBean v = new LocalValidatorFactoryBean();
v.setProviderClass(ApacheValidationProvider.class);
return v;
}
调用校验
手动校验方法,先试试
@Autowired
LocalValidatorFactoryBean v;
public List<DataDict> getDataDict(Long parentId) {
List<DataDict> list = DataDictDao.DataDictDAO.setWhereQuery("parentId", parentId).findList();
Validator validator = v.getValidator();
Set<ConstraintViolation<DataDict>> violations = validator.validate(list.get(0));
System.out.println(violations.size()); // 校验结果
System.out.println(list.get(0).getParentId());
if (CollectionUtils.isEmpty(list))
list = new ArrayList<>();
return list;
}
上述代码是对一个 Java Bean:DataDict 进行校验,Bean 的字段可配置如下的约束。
public class DataDict implements CommonEntity {
/** * 主键 id,自增 */
private Long id;
/** * 父 id */
@NotNull
private Long parentId;
/** * 类型 id */
@NotNull
private Long type;
……
}
更多校验注解参见旧文。
Spring MVC 自动校验
很简单,添加注解 @Valid
在 Bean 参数上。
/** * 新建 * @return */
@RequestMapping(method = RequestMethod.POST)
public String create(@Valid T news, Model model) {
System.out.println("新建");
if (result.hasErrors()) {
LOGGER.info("create error!");
}else{
LOGGER.info("create ok!");
}
news.setService(getService());
try {
getService().create(news);
model.addAttribute("newlyId", news.getId());
} catch (ServiceException e) {
model.addAttribute("errMsg", e.toString());
}
return "common/entity/json_cud";
}
接着说说怎么处理错误,或者不处理默认交由 Servlet 处理也可以。下面是自定义异常的处理器,转化为 JSON 返回。
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import com.ajaxjs.util.WebHelper;
/** * 后端表单、数据校验的异常捕获 * * @author Frank Cheung<[email protected]> * */
@ControllerAdvice
public class RestResponseEntityExceptionHandler {
static final String TPL = "输入字段 [%s] 未通过校验,原因 [%s],输入值为 [%s],请检查后再提交。";
@ExceptionHandler(value = BindException.class)
public void exceptionHandler(HttpServletRequest req, HttpServletResponse resp, BindException e) {
String msg = "";
List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
for (FieldError err : fieldErrors) {
msg += String.format(TPL, err.getField(), err.getDefaultMessage(), err.getRejectedValue());
// msg += "\\\\n";
}
ResponseResult result = new ResponseResult();
result.setErrorCode("400");
result.setMessage(msg);
WebHelper.outputJson(resp, result.toString());
}
}
这个 RestResponseEntityExceptionHandler 按照正常注入 Spring 组件方式即可,下面是一种方法:
@Bean
RestResponseEntityExceptionHandler initRestResponseEntityExceptionHandler() {
return new RestResponseEntityExceptionHandler();
}
JSR 303 可以自定义约束的原因,这样就不会输出默认的英文,但要逐个说明也比较麻烦。
另外有个 getAllErrors,这个不是针对字段的,估计是 for 校验方法的。
List<ObjectError> allErrors = e.getAllErrors();
for (ObjectError err : allErrors) {
msg += err.getDefaultMessage();
msg += StringUtils.arrayToDelimitedString(err.getCodes(), ",");
}
高级用法
Apache BVal 的功能还远不止这些,可以参考老外的文章学习更多高级用法。
边栏推荐
- idea彻底卸载安装及配置笔记
- Differences between rip and OSPF and configuration commands
- Recommend free online SMS receiving platform in 2022 (domestic and foreign)
- 【Unity Shader】插入Pass实现模型遮挡X光透视效果
- Calculation of torque target value (ftorque) in servo torque control mode
- 来了!GaussDB(for Cassandra)新特性亮相
- PTA 1102 教超冠军卷
- Redis的发布与订阅
- 学习open62541 --- [67] 添加自定义Enum并显示名字
- 云安全日报220707:思科Expressway系列和网真视频通信服务器发现远程攻击漏洞,需要尽快升级
猜你喜欢
Datasimba launched wechat applet, and datanuza accepted the test of the whole scene| StartDT Hackathon
【Unity Shader】插入Pass实现模型遮挡X光透视效果
Do you really understand sticky bag and half bag? 3 minutes to understand it
idea彻底卸载安装及配置笔记
Improve application security through nonce field of play integrity API
debian10系统问题总结
现货白银分析中的一些要点
CVPR 2022 - learning non target knowledge for semantic segmentation of small samples
Save the memory of the model! Meta & UC Berkeley proposed memvit. The modeling time support is 30 times longer than the existing model, and the calculation amount is only increased by 4.5%
Discuss | what preparations should be made before ar application is launched?
随机推荐
强化学习-学习笔记8 | Q-learning
[paper sharing] where's crypto?
卖空、加印、保库存,东方甄选居然一个月在抖音卖了266万单书
Charles+drony的APP抓包
用存储过程、定时器、触发器来解决数据分析问题
Static routing configuration
Kirk Borne的本周学习资源精选【点击标题直接下载】
Simple configuration of single arm routing and layer 3 switching
Debian10 compile and install MySQL
Cloud security daily 220707: Cisco Expressway series and telepresence video communication server have found remote attack vulnerabilities and need to be upgraded as soon as possible
Summary of debian10 system problems
Yearning-SQL审核平台
『HarmonyOS』DevEco的下载安装与开发环境搭建
socket编程之常用api介绍与socket、select、poll、epoll高并发服务器模型代码实现
Improve application security through nonce field of play integrity API
能同时做三个分割任务的模型,性能和效率优于MaskFormer!Meta&UIUC提出通用分割模型,性能优于任务特定模型!开源!...
Backup Alibaba cloud instance OSS browser
Interview vipshop internship testing post, Tiktok internship testing post [true submission]
Learn to make dynamic line chart in 3 minutes!
Five network IO models