【问题标题】:Spring valid annotation not working in controllerSpring有效注释在控制器中不起作用
【发布时间】:2021-06-24 12:15:48
【问题描述】:

我有一个问题:我的 post 表单工作正常,与 post 方法相关的控制器确实从 HTML post 表单接收对象,但 @Valid 注释什么也不做。 在BindingResult 对象中没有错误,即使它应该在那里

问题出在:itemAddControllerPost()

package orchowski.tomasz.ecommercedemo.controller.item;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import orchowski.tomasz.ecommercedemo.command.ItemCommand;
import orchowski.tomasz.ecommercedemo.converter.ItemCommandToItem;
import orchowski.tomasz.ecommercedemo.converter.ItemToItemCommand;
import orchowski.tomasz.ecommercedemo.domain.Item;
import orchowski.tomasz.ecommercedemo.security.permision.PermissionStoreItemCreate;
import orchowski.tomasz.ecommercedemo.security.permision.PermissionStoreItemRead;
import orchowski.tomasz.ecommercedemo.services.ItemService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
import java.util.List;
import java.util.Optional;

@Slf4j
@Controller
@RequestMapping("/item")
@RequiredArgsConstructor
public class ItemController {

    private final ItemService itemService;
    private final ItemCommandToItem commandToItem;
    private final ItemToItemCommand itemToCommand;

    @PermissionStoreItemCreate
    @GetMapping("/create")
    public String itemAddController(Model model) {
        model.addAttribute("item", new ItemCommand());
        return "item/itemform";
    }

    @PermissionStoreItemCreate
    @PostMapping("/create/new")
    public String itemAddControllerPost(@ModelAttribute("item") @Valid ItemCommand itemCommand, BindingResult bindingResult) {
        log.debug("Posting new item object");
        if (bindingResult.hasErrors()) {
                bindingResult.getAllErrors().forEach(objectError -> log.error(objectError.toString()));
            log.debug("Binding error");
            return "redirect:/item/create";
        }
        Item save = itemService.save(commandToItem.convert(itemCommand));
        log.debug("New item object persisted to db \n " + save.toString());
        return "redirect:/item/" + save.getId() + "/show";
    }

    @PermissionStoreItemRead
    @GetMapping("/show")
    public String itemRead(Model model, HttpServletRequest request, @RequestParam(defaultValue = "0") Integer pageNo,
                           @RequestParam(defaultValue = "10") Integer pageSize) {
        ///item/show?pageNo=2&pageSize=20

        if (pageNo < 0 || pageSize <= 0) {
            return "redirect:/item/show?pageNo=0";
        }
        model.addAttribute("pageNumber", pageNo);
        model.addAttribute("pageSize", pageSize);

        List<Item> itemList = itemService.findAll(pageNo, pageSize);
        if (itemList.size() == 0) {
            return "redirect:/item/show?pageNo=" + (pageNo - 1);
        }
        model.addAttribute("items", itemList);
        System.out.println(itemList);
        return "item/show";
    }

    @GetMapping("/{id}/show")
    @PermissionStoreItemRead
    public String showItem(Model model,@PathVariable Long id) {
        Optional<Item> byId = itemService.findById(id);
        model.addAttribute("item", byId.orElseThrow(() -> new RuntimeException("Item id " + id + " not found")));
        return "item/showProduct";
    }
}

我的命令对象

package orchowski.tomasz.ecommercedemo.command;


import lombok.*;
import javax.validation.constraints.*;


@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ItemCommand {

    private Long id;

    @Size(min = 20, max = 1000,message = "Description must contains at least 20 characters and less than 1000")
    @NotBlank
    private String description;

    @Min(value = 0, message = "Price have to be greater than 0")
    @NotNull
    private Double price;

    @Min(value = 0, message = "Stock have to be at least 0")
    @NotNull
    private Integer stock;

}

html表单


    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org"
          xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
    <head>
        <meta charset="UTF-8">
        <title>store</title>
        <link th:rel="stylesheet" th:href="@{/webjars/bootstrap/5.0.1/css/bootstrap.min.css}">
        <link th:rel="stylesheet" th:href="@{/css/default.css}">
    </head>
    <body>
    
    <div class="container">
        <div class="row">
            <div class="col-sm-12">
                <nav th:replace="fragments/navbar :: nav"></nav>
            </div>
        </div>
    
        <form th:object="${item}" th:action="@{/item/create/new}" method="post">
            <div class="row">
                <div class="mb-3">
                    <!--description            -->
                    <label for="description" class="form-label">Description of product</label>
                    <textarea class="form-control" id="description" name="description"></textarea>
                </div>
            </div>
            <div class="row">
                <div class="col-sm-3">
                    <!--price            -->
                    <label for="price">Price of product</label>
                    <input type="text" class="form-control" id="price" name="price">
                </div>
                <div class="col-sm-3">
                    <!--stock            -->
                    <label for="stock">Stock item</label>
                    <input type="text" class="form-control" id="stock" name="stock">
                </div>
            </div>
            <div class="row">
                <button type="submit" class="btn btn-primary">Submit</button>
            </div>
        </form>
    
    </div>
    
    
    <script th:src="@{/webjars/jquery/3.0.0/jquery.min.js}"></script>
    <script th:src="@{/webjars/popper.js/2.9.2/umd/popper.js}"></script>
    <script th:src="@{/webjars/bootstrap/5.0.1/js/bootstrap.js}"></script>
    </body>
    </html>

查看GitHub上的代码please click here

【问题讨论】:

  • 尝试在ItemController添加@Validated

标签: java spring validation


【解决方案1】:

试试:

import javax.validation.Valid;

https://docs.oracle.com/javaee/7/api/javax/validation/Valid.html

代替:

import jakarta.validation.Valid;

(一个模棱两可的导入!;)


有用的阅读:https://www.google.com/search?q=spring+valild@javax.validation.Valid@org.springframework.validation.annotation.Validated


进一步阅读:

JSR 303


jakarta.validation.Valid : ??? (SpringBoot with Jakarta Validation Api not validating with @Valid Annotationhttps://www.google.com/search?q=jakarta.validation.Valid(看起来已经过时了!???))检查你的类路径/依赖树!


实际上我发现没有/很少有示例,其中明确提到了导入语句,但它是"clear" that spring supports JSR 303 (即javax.validation.*而不是 jakarta.validation.*..)

【讨论】:

  • 谢谢你的回答:)!
  • 工作:3!问题在于休眠依赖
【解决方案2】:

问题已经解决了!

我在 pom.xml 中更改了休眠依赖项 来自

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>7.0.1.Final</version>
        </dependency>

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1.5.Final</version>
</dependency>

【讨论】:

  • 最佳/记录:spring-boot-starter-validation ;)
猜你喜欢
  • 2015-11-15
  • 1970-01-01
  • 2014-04-20
  • 1970-01-01
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 2015-10-26
  • 2016-06-02
相关资源
最近更新 更多