You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+Thymeleaf实现字段依赖校验:覆盖值需小于计算值

Spring Boot + Thymeleaf 实现覆盖值小于计算值的校验方案

一、后端校验(保障数据合法性)

后端校验是核心防线,可避免前端校验被绕过导致非法数据入库。

1. 实体类添加自定义校验逻辑

在表单对应的实体类中,通过@AssertTrue注解标记校验方法,实现覆盖值小于计算值的规则:

import javax.validation.constraints.NotNull;
import javax.validation.constraints.AssertTrue;

public class CalculationForm {
    @NotNull(message = "计算值不能为空")
    private Integer calculatedValue;

    private Integer overridingValue;

    // 自定义校验:覆盖值小于计算值,若覆盖值为空则默认合法
    @AssertTrue(message = "覆盖值必须小于计算值")
    public boolean isOverridingValueValid() {
        if (calculatedValue == null) {
            return true; // 计算值为空的情况由@NotNull单独校验
        }
        return overridingValue == null || overridingValue < calculatedValue;
    }

    // Getter & Setter
    public Integer getCalculatedValue() { return calculatedValue; }
    public void setCalculatedValue(Integer calculatedValue) { this.calculatedValue = calculatedValue; }
    public Integer getOverridingValue() { return overridingValue; }
    public void setOverridingValue(Integer overridingValue) { this.overridingValue = overridingValue; }
}

2. Controller处理表单提交

在Controller中用@Valid触发校验,通过BindingResult捕获错误,返回表单页面展示错误信息:

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import javax.validation.Valid;

@Controller
public class CalculationController {

    @GetMapping("/calculation")
    public String showForm(Model model) {
        model.addAttribute("calculationForm", new CalculationForm());
        return "calculation-form";
    }

    @PostMapping("/calculation")
    public String submitForm(@Valid CalculationForm calculationForm, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            // 校验失败,返回原表单展示错误
            return "calculation-form";
        }
        // 校验通过,执行业务逻辑
        return "success";
    }
}

二、前端校验(提升用户体验)

前端实时校验能让用户在输入时立刻得到反馈,无需等待表单提交。

1. Thymeleaf页面渲染后端错误

在表单页面中,通过Thymeleaf的表单错误表达式展示后端返回的校验提示:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>计算表单</title>
</head>
<body>
    <form th:action="@{/calculation}" th:object="${calculationForm}" method="post">
        <div>
            <label>计算值:</label>
            <input type="number" th:field="*{calculatedValue}" />
            <span th:if="${#fields.hasErrors('calculatedValue')}" th:errors="*{calculatedValue}" style="color: red;"></span>
        </div>
        <div>
            <label>覆盖值:</label>
            <input type="number" th:field="*{overridingValue}" id="overridingInput" />
            <span th:if="${#fields.hasErrors('overridingValue')}" th:errors="*{overridingValue}" style="color: red;"></span>
            <!-- 前端实时错误提示 -->
            <span id="frontError" style="color: red; display: none;">覆盖值必须小于计算值</span>
        </div>
        <button type="submit">提交</button>
    </form>

    <script>
        const calculatedInput = document.querySelector('[name="calculatedValue"]');
        const overridingInput = document.querySelector('#overridingInput');
        const frontError = document.querySelector('#frontError');

        // 实时校验逻辑
        function validate() {
            const calculatedVal = parseInt(calculatedInput.value);
            const overridingVal = parseInt(overridingInput.value);

            if (!isNaN(calculatedVal) && !isNaN(overridingVal) && overridingVal >= calculatedVal) {
                frontError.style.display = 'inline';
            } else {
                frontError.style.display = 'none';
            }
        }

        // 监听输入变化
        calculatedInput.addEventListener('input', validate);
        overridingInput.addEventListener('input', validate);

        // 提交前二次校验
        document.querySelector('form').addEventListener('submit', function(e) {
            validate();
            if (frontError.style.display === 'inline') {
                e.preventDefault(); // 阻止非法提交
            }
        });
    </script>
</body>
</html>

补充说明

  • 如果需要支持小数类型,只需将实体类中的Integer改为Double,JS中替换parseInt为parseFloat即可;
  • 后端校验不可省略,即使做了前端校验,也必须保留后端校验来拦截非法请求。

内容的提问来源于stack exchange,提问作者Syed Iftekharuddin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 08:40:48