Thymelaf在春季的表单验证问题



我正在制作一个spring-web计算器,它接收名为"的模板中的输入;计算器",将其发送到后端,对其进行验证,如果输入与模式匹配,则计算结果并将其显示在另一个名为"的模板中;结果";问题是,如果我的输入与模式不匹配,它必须返回一条错误消息。为此,我使用了";th:如果";。但相反,它抛出了400个坏请求错误。这是我的代码:控制器`

@Controller
public class CalculationController implements WebMvcConfigurer {
@GetMapping("/")
public String showForm(CalculatorForm calculatorForm) {
//model.addAttribute("calculatorForm", new CalculatorForm());
return "calculator";
}
@PostMapping("/")
public String checkCalcValue(@Valid CalculatorForm calculatorForm, Model model, Errors errors) {
if(errors.hasErrors()){
return "calculator";
}
CalculationService service = new CalculationService();
calculatorForm.setCalculationResult(service.calculate(calculatorForm.getCalculationValue()));
System.out.println(calculatorForm.getCalculationValue());
model.addAttribute("calculatorForm", calculatorForm);
return "result";
}
}

**Service**

public class CalculationService {
public double calculate(String toCalculate) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(toCalculate);
Double result = exp.getValue(Double.class);
return result;
}
}

**Model**

public class CalculatorForm {
@NotEmpty
@Pattern(regexp="([0-9]|[\-+*/])+",message="only math expressions")
private String calculationValue;
private Double calculationResult;
public String getCalculationValue() {
return calculationValue;
}
public void setCalculationValue(String newCalculationValue){
calculationValue = newCalculationValue;
}
public void setCalculationResult(Double newCalculationResult){
calculationResult = newCalculationResult;
}
public Double getCalculationResult(){
return calculationResult;
}
}

**Calculator template**


<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Your first Spring application</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p><a href="/calculator">Calculator</a></p>
<form action="#" th:action="@{/}" th:object="${calculatorForm}" method="post">
<table>
<tr>
<td>Calculator:</td>
<td><input value="" type="text" th:field="*{calculationValue}" name="calculationValue" id="calculationValue"/></td>
<td th:if="${#fields.hasErrors('calculationValue')}" th:errors="*{calculationValue}">Calculation Error</td>
</tr>
<tr>
<br/>
<input type="button" onclick="input(this);" id="buttonOne" value="1"></input>
<input type="button" onclick="input(this);" id="buttonTwo" value="2"></input>
<input type="button" onclick="input(this);" id="buttonThree" value="3"></input>
<br/>
<input type="button" onclick="input(this);" id="buttonFour" value="4"></input>
<input type="button" onclick="input(this);" id="buttonFive" value="5"></input>
<input type="button" onclick="input(this);" id="buttonSix" value="6"></input>
<br/>
<input type="button" onclick="input(this);" id="buttonSeven" value="7"></input>
<input type="button" onclick="input(this);" id="buttonEight" value="8"></input>
<input type="button" onclick="input(this);" id="buttonNine" value="9"></input>
<br/>
<input type="button" onclick="input(this);" id="buttonZero" value="0"></input>
<input type="button" onclick="input(this);" id="buttonPlus" value="+"></input>
<input type="button" onclick="input(this);" id="buttonMinus" value="-"></input>
<br/>
<input type="button" onclick="input(this);" id="buttonMultiply" value="*"></input>
<input type="button" onclick="input(this);" id="buttonDivide" value="/"></input>
<input type="button" onclick="remove();" id="remove" value="<-"></input>
<br/>
</tr>
<tr>
<td><button type="submit">Submit</button></td>
</tr>
<input type="button" onclick="delAll();" id="delete" value="DEL"></input>
</table>
</form>
<script>
function input(button){
let calculationValue = document.getElementById("calculationValue");
calculationValue.value += button.value;
}
function remove(){
let calculationValue = document.getElementById("calculationValue");
calculationValue.value = calculationValue.value.substring(0, calculationValue.value.length - 1);
}
function delAll(){
let calculationValue = document.getElementById("calculationValue");
calculationValue.value = "";
}

</script>
</body>
</html>

**Result template**


<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Your first Spring application</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p><a href="/calculator">Calculator</a></p>
<form action="#" th:action="@{/}" th:object="${calculatorForm}" method="post">
<table>
<tr>
<td>Calculator:</td>
<td><input value="" type="text" th:field="*{calculationValue}" name="calculationValue" id="calculationValue"/></td>
<td th:if="${#fields.hasErrors('calculationValue')}" th:errors="*{calculationValue}">Calculation Error</td>
</tr>
<tr>
<br/>
<input type="button" onclick="input(this);" id="buttonOne" value="1"></input>
<input type="button" onclick="input(this);" id="buttonTwo" value="2"></input>
<input type="button" onclick="input(this);" id="buttonThree" value="3"></input>
<br/>
<input type="button" onclick="input(this);" id="buttonFour" value="4"></input>
<input type="button" onclick="input(this);" id="buttonFive" value="5"></input>
<input type="button" onclick="input(this);" id="buttonSix" value="6"></input>
<br/>
<input type="button" onclick="input(this);" id="buttonSeven" value="7"></input>
<input type="button" onclick="input(this);" id="buttonEight" value="8"></input>
<input type="button" onclick="input(this);" id="buttonNine" value="9"></input>
<br/>
<input type="button" onclick="input(this);" id="buttonZero" value="0"></input>
<input type="button" onclick="input(this);" id="buttonPlus" value="+"></input>
<input type="button" onclick="input(this);" id="buttonMinus" value="-"></input>
<br/>
<input type="button" onclick="input(this);" id="buttonMultiply" value="*"></input>
<input type="button" onclick="input(this);" id="buttonDivide" value="/"></input>
<input type="button" onclick="remove();" id="remove" value="<-"></input>
<br/>
</tr>
<tr>
<td><button type="submit">Submit</button></td>
</tr>
<input type="button" onclick="delAll();" id="delete" value="DEL"></input>
</table>
</form>
<script>
function input(button){
let calculationValue = document.getElementById("calculationValue");
calculationValue.value += button.value;
}
function remove(){
let calculationValue = document.getElementById("calculationValue");
calculationValue.value = calculationValue.value.substring(0, calculationValue.value.length - 1);
}
function delAll(){
let calculationValue = document.getElementById("calculationValue");
calculationValue.value = "";
}

</script>
</body>
</html>

`

我尝试在控制器中使用断点进行调试;如果(errors.hasErrors(((";线如果输入与模式匹配,它将返回零个错误,编译将继续,但有趣的是,如果输入与该模式不匹配,它就不会到达断点——断点具有映射后注释,这意味着在到达必须返回错误消息的代码部分之前,某些东西会停止编译并抛出400个错误。

来自Web MVC参考文档:

必须在经过验证的方法参数之后立即声明ErrorsBindingResult参数。

您将Model参数放在已验证的表单和Errors之间。

最新更新