Как именно работает метод supports() интерфейса Spring Validator?

Я довольно новичок в Spring MVC, и у меня есть следующие сомнения относительно того, как работает этот пример валидатора:

Итак, у меня есть эта страница search.jsp, на которой пользователь может искать продукт по двум критериям (название продукта и категория, к которой принадлежит продукт):

<%@ 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>

Итак, в туториале вводятся некоторые ограничения на ввод 2-х полей предыдущего представления, реализующего настраиваемый валидатор. В частности, пользователь должен:

1) Пользователь должен вставить название продукта или категорию

2) Длина имени должна состоять как минимум из 3 символов.

3) Пользователь может выбирать только по имени или категории, но не по какому-либо другому полю объекта модели Product.

Для реализации этого пользовательского валидатора создается этот класс ProductSearchValidator, реализующий интерфейс Spring Validator:

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() говорит, можно ли проверить конкретный экземпляр класса из этого валидатора, а метод validate() реализует конкретную логику проверки.

Хорошо, метод validate() мне довольно ясен (он реализует предыдущие 3 указанных ограничения).

Я не могу понять, как именно метод supports()

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

Как именно работает? Что представляет собой его входной параметр (Класс clazz)? А что представляет собой возвращенное логическое значение? (в чем смысл оценки Product.class.isAssignableFrom(clazz)?)

Tnx


person AndreaNobili    schedule 06.09.2015    source источник


Ответы (1)


метод supports() говорит, можно ли проверить конкретный экземпляр класса из этого валидатора

Нет. Там указано, поддерживается ли конкретный класс валидатором. При проверке объекта сам объект не передается в supports(). В supports() передается класс объекта.

Итак, перед проверкой экземпляра Product Spring вызывает supports() с Product.class в качестве аргумента.

Перед проверкой экземпляра SubClassOfProduct Spring вызывает supports() с SubClassOfProduct.class в качестве аргумента.

В обоих случаях, поскольку Product.class назначается из Product.class/SubclassOfProduct.class, метод возвращает значение true. Если вы попытаетесь проверить пользователя с помощью этого валидатора, он вернет false. Действительно, вы можете сделать

Product p = someProductInstance;

Вы также можете сделать

Product p = someSubClassOfProductInstance;

Но ты не можешь сделать

Product p = someUserInstance;

Вот что означает Product.class.isAssignableFrom(clazz).

См. соответствующие javadocs, которые в основном объясняют то, что я только что объяснил:

person JB Nizet    schedule 06.09.2015
comment
как обычно, ваши объяснения идеальны, спасибо :-) - person AndreaNobili; 07.09.2015