使用@Valid 和 Thymeleaf 验证 spring-boot 中的输入

Validating input in spring-boot using @Valid andThymeleaf

我尝试验证实体 class 的 2 个字段,该实体有 2 个字段:名称和价格,但两个字符串和我都尝试从每个 @NotBlank(message = "..." ) 到输入字段下的表单中。但我收到这些错误:

Field error in object 'foodDto' on field 'name': rejected value []; codes [NotBlank.foodDto.name,NotBlank.name,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [foodDto.name,name]; arguments []; default message [name]]; default message [Name required] Field error in object 'foodDto' on field 'price': rejected value []; codes [NotBlank.foodDto.price,NotBlank.price,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [foodDto.price,price]; arguments []; default message [price]]; default message [Price required]]

package com.assignment2.project.dto;


import javax.validation.constraints.NotBlank;

public class FoodDto {

@NotBlank(message = "Name required")
public String name;
@NotBlank(message = "Price required")
public String price;

public FoodDto(String name, String price) {
    this.name = name;
    this.price = price;
}

public FoodDto() {
}

@Override
public String toString() {
    return "FoodDto{" +
            "name='" + name + '\'' +
            ", price='" + price + '\'' +
            '}';
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getPrice() {
    return price;
}

public void setPrice(String price) {
    this.price = price;
}
}
 /////////////////////////////////////////////////
@Controller
@RequestMapping("food")
public class FoodController{

@Autowired
FoodService foodService;

@Autowired
ReportPDFService reportPDFService;

@GetMapping("create")
public String createFood(Model model){
    model.addAttribute("title","Create Food");
    String type = reportPDFService.readFile();
    model.addAttribute("user",new User(Integer.parseInt(type)));
    model.addAttribute("food", new FoodDto());
    return "food/create";
}

@PostMapping("create")
public String renderCreatedFood(@ModelAttribute @Valid FoodDto newFood, Model model, BindingResult errors){
    if(errors.hasErrors()){
        System.out.println("heree?");
        model.addAttribute("title","Create Food");
        return "food/create";
    }
    foodService.create(newFood);
    return "redirect:create";
}
////////////////////
<form method="post">
<div class="form-group">
    <label>Name
        <input th:field="${food.name}" class="form-control">
    </label>
    <p class="error" th:errors="${food.name}"></p>
</div>

<div class="form-group">
    <label>Price
        <input th:field="${food.price}" class="form-control">
    </label>
    <p class="error" th:errors="${food.price}"></p>
</div>

<div class="form-group">
    <input type="submit" value="Create" class="btn btn-success">
</div>

</form>

我没有在 html 文件的字段下给我错误,而是在应用程序和网络上给我一个错误:

在你的代码中,我认为 BindingResult 应该紧跟在 newFood 之后。

renderCreatedFood(Model model, @Valid FoodDto newFood, BindingResult errors)

In your controller handler method, try moving the BindingResult argument so it is immediately after the command argument. Spring looks for command object parameters and BindingResult parameters to be paired up in handler method signatures.

我用 reference here 创建了一个类似的例子,我想你想要这个!

此处,如果名称或价格字段包含空值;您的消息出现在输入的旁边。

public class FoodDTO {

    @NotBlank(message = "Name required!")
    public String name;

    @NotBlank(message = "Price required!")
    public String price;

    public FoodDTO() {
    }

    // getter/setter ..
}
@Controller
@RequestMapping("food")
public class FoodController {

    @GetMapping("/create")
    public String crete(FoodDTO foodDTO) {
        return "food-form";
    }

    @PostMapping("/insert")
    public String insert(@Valid FoodDTO foodDTO, BindingResult bindingResult) {

        if (bindingResult.hasErrors()) {
            return "food-form";
        }

        return "redirect:/food/result";
    }

    @GetMapping("/result")
    public String result() {
        return "result";
    }
}
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
    <form action="/food/insert" method="post" th:object="${foodDTO}">
        <table>
            <tr>
                <td>Name:</td>
                <td><input type="text" th:field="*{name}" /></td>
                <td th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</td>
            </tr>
            <tr>
                <td>Price:</td>
                <td><input type="text" th:field="*{price}" /></td>
                <td th:if="${#fields.hasErrors('price')}" th:errors="*{price}">Price Error</td>
            </tr>
            <tr>
                <td><button type="submit">Submit</button></td>
            </tr>
        </table>
    </form>
</body>
</html>