java - Spring MVC 验证和 Thymeleaf - 验证整数字段
问题描述
我正在将 .net 项目移至 Spring Boot。所以问题是如何在 Spring 中正确验证 Integer 字段。我有一个带有整数字段的实体:
@Entity
@Table(name = "tb_employee")
public class EmployeeDev {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "empl_id")
private int emplId;
@Range(min = 10, max = 50, message="Numbers only between 10 and 50")
@Column(name = "default_vacation_days", nullable = true)
private Integer defaultVacationDays;
...和一个捕获错误的控制器:
// update employee
@PostMapping("/edit")
public String showFormForUpdate(@Valid @ModelAttribute("employee") EmployeeDev employee, Errors errors,
RedirectAttributes redirectAttributes,
Model theModel) {
if (null != errors && errors.getErrorCount() > 0) {
List<ObjectError> errs = errors.getAllErrors();
String errMsg = "";
for (ObjectError e :errs)
errMsg += e.getDefaultMessage();
theModel.addAttribute("message", "Employee Edit failed. " + errMsg );
theModel.addAttribute("alertClass", "alert-danger");
return "employeesdev/employee-form-edit";
}
现在的问题是,当我在默认假期字段中输入超出范围的任何数字时,它会显示正确的验证消息:数字仅在 10 到 50 之间。
但是,如果我尝试插入类似 1A 的内容(可能是用户拼写错误),我会收到以下消息: Failed to convert property value of type java.lang.String to required type java.lang.Integer for property defaultVacationDays; 嵌套异常是 java.lang.NumberFormatException:对于输入字符串:“1A”
我知道这是正确的消息,但我讨厌向用户显示这样的消息。我宁愿只显示“仅在 10 到 50 之间的数字”而不是数据类型转换问题。为什么要用 Java 数据类型打扰用户?
我将不胜感激任何建议。
解决方案
If you want get custom behaviour from the annotation you need to define your own constriant annotation and validator for this annotation.
Here is basic example of custom constraint annotation:
@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = CheckCalculationTypeValidator.class)
@Documented
public @interface CheckCalculationType {
String message() default "calculation_type shall be not NULL if status = active";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
and validator:
public class CheckCalculationTypeValidator implements ConstraintValidator<CheckCalculationType, RequestDto> {
@Override
public boolean isValid(RequestDto dto, ConstraintValidatorContext constraintValidatorContext) {
if (dto == null) {
return true;
}
return !(Status.ACTIVE.equals(dto.getStatus()) && dto.getCalculationType() == null);
}
@Override
public void initialize(CheckCalculationType constraintAnnotation) {
// NOP
}
}
Required dependency for Hibernate Validator:
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.2.Final</version>
</dependency>
推荐阅读
- redis - 关机或重启时保持 Celery Queue
- unity3d - unity Frustum Culling with drawmesh 太早了
- python-3.x - Python:同时从两个 websocket 获取数据并处理它
- c++ - 为什么不能被 4 整除且宽度大于 32 像素的位图图像在创建像素数据数组时会导致错误的行扫描?
- authentication - Keycloak:有没有办法在使用“更新配置文件”所需的操作时使名字和姓氏不可编辑?
- r - 在R包`T-LoCoH`中计算s = 0时的时间重叠船体
- amazon-web-services - AWS CodeBuild 作业如何查看哪些文件已更改?
- kotlin - Kotlin 1.5.0 项目升级
- gnu - Kleopatra 管理员无法启动
- elasticsearch - 在 ES 查询中添加后过滤器作为 URL