java - Spring Validator 接口(interface)的 supports() 方法到底是如何工作的?

标签 java spring validation spring-mvc spring-validator

我是 Spring MVC 的新手,我对这个 validator 示例的工作原理有以下疑问:

所以我有这个 search.jsp 页面,用户可以在其中通过 2 个字段标准(产品名称和产品所属的类别)搜索产品:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Search</title>
<jsp:include page="/WEB-INF/views/include/head-include.jsp" />
</head>
<body>
    <div class="container">
    <h2>Search Products</h2>
    <div class="form-group form">
    <form:form name="input"  method="get"
        modelAttribute="product" action="products">
        <div>
            <label>Name: </label>
            <form:input type="text" path="name" class="form-control"  />
            <form:errors path="name" />
        </div>
        <div>
            <label>Category:</label>
            <form:select path="category.id" class="form-control" >
                <form:option path="category.id" value="0" label="--- All Categories ---"/>
                <form:options path="category.id" items="${categories}" itemLabel="name" itemValue="id" />
            </form:select>
        </div>
        <div>
            <input type="submit" value="Submit" class="form-control">
        </div>


    </form:form>
    </div>

    <h2>Search Results:</h2>

    <c:forEach var="product" items="${results}">
        <c:out value="${product.name}"/> <br/>
    </c:forEach>
    </div>

</body>
</html>

因此,在教程中引入了一些对实现自定义 validator 的先前 View 的 2 个字段的输入的限制。在特定情况下,用户必须:

1) 用户必须插入产品名称或类别

2) 名称长度必须至少由3个字符组成。

3) 用户只能按名称或类别进行选择,而不能在Product 模型对象的某些其他字段上进行选择

为了实现这个自定义 validator ,它创建了这个实现了 Spring Validator 接口(interface)的 ProductSearchValidator 类:

package com.packtpub.springmvc.chocolatestore;

import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import com.packtpub.springmvc.chocolatestore.model.Product;

@Component
public class ProductSearchValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return Product.class.isAssignableFrom(clazz);  
    }

    @Override
    public void validate(Object target, Errors errors) {
        Product product = (Product) target;
        String name = product.getName();
        if (!StringUtils.hasLength(name) && (product.getCategory() == null || product.getCategory().getId() == 0)) {
            errors.rejectValue("name", "required", "Either name or category is required");
        } else if ((product.getCategory() == null || product.getCategory().getId() == 0) && name.trim().length() < 3) {
            errors.rejectValue("name", "tooShort", "Please enter at least 3 letters");
        }

    }

}

根据我的理解,supports() 方法说明类的特定实例是否可以从此 validator 进行验证,而 validate() 方法实现特定的验证逻辑。

好的,validate() 方法对我来说很清楚(它实现了前面 3 个指定的限制)。

我不明白的是 supports() 方法究竟是怎么做的

@Override
public boolean supports(Class<?> clazz) {
    return Product.class.isAssignableFrom(clazz);  
}

具体是如何运作的?什么代表它的输入参数(Class clazz)?什么代表返回的 boolean 值? (Product.class.isAssignableFrom(clazz) 评估的意义是什么?)

谢谢

最佳答案

the supports() method say if a specific instance of a class can be validate from this validator

没有。它表示 validator 是否支持特定类。验证对象时,对象本身不会传递给 supports()。传递给 supports() 的是对象的类。

因此,在验证 Product 实例之前,Spring 以 Product.class 作为参数调用 supports()

在验证 SubClassOfProduct 实例之前,Spring 以 SubClassOfProduct.class 作为参数调用 supports()

在这两种情况下,由于 Product.class 可从 Product.class/SubclassOfProduct.class 分配,因此该方法返回 true。如果您尝试使用该 validator 验证用户,它将返回 false。的确,你可以做到

Product p = someProductInstance;

你也可以这样做

Product p = someSubClassOfProductInstance;

但是你做不到

Product p = someUserInstance;

这就是 Product.class.isAssignableFrom(clazz) 的意思。

查看相关的javadocs,基本解释了我刚才解释的内容:

关于java - Spring Validator 接口(interface)的 supports() 方法到底是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32425576/

相关文章:

java - 如何使用值谓词过滤 HashMap?

java - 在 @Transactional 中提交 try-catch 中的更改

java - 如何在java中使用split创建二维数组列表?

Java JFrame - 在另一个线程完成之前不重绘()

java - 在另一个 Web 应用程序中重用 DAO

html - 我可以使用 HTML5 验证 2 input[type=email] 匹配吗?

java - jpa 验证分离对象

java - 在java中验证对象的最佳方法

java - 是否可以在 Java 中使用通用 Consumer 作为函数参数?

spring - 使用 maven(不是 gradle)生成带有 spring rest docs 的 asciidoctor doc