Невозможно отобразить ошибки проверки для компонента, поддерживающего форму

1

Я с трудом пытаюсь показать ошибки проверки в моем приложении Spring MVC с использованием бланка формы и сложных объектов в этом компоненте, поддерживающем форму.

Похоже, что функция hasErrors не поддерживает "." символов или не может разрешать сложные объекты?

При загрузке следующего кода я могу показать форму. Однако после того, как валидатор найдет нулевое имя автора и перезагрузит страницу create.html, я получаю стоп-лосс о том, как Thymeleaf/Spring не может оценить мое выражение SPel.

Кто-нибудь знает, почему он пытается загрузить " author.author ", когда выражение выражает "author.name"? Это как будто собственность получает "автор". добавлено к выражению.

ОБНОВЛЕНИЕ: после многого устранения неполадок, я обнаружил, что валидатор был проблемой, хотя пока не знаю, почему.

Я включил валидаторы.

AuthorCommandObject.java

public class AuthorCommandObject {
    private Author _author;
    private Book _book;

    public Author getAuthor() {
        return _author;
    }

    public void setAuthor(Author author) {
        _author = author;
    }

    public Author getBook() {
        return _book;
    }

    public void setBook(Book book) {
        _book = book;
    }
}

Author.java

public class Author {
    private long _authorId;
    private String _name;

    public long getAuthorId() {
        return _authorId;
    }

    public void setAuthorId(long authorId) {
        _authorId = authorId;
    }

    public String getName() {
        return _name;
    }

    public void setName(String name) {
        _name = name;
    }
}

Book.java

public class Book {
    private long _bookId;
    private String _bookName;

    public long getBookId() {
        return _bookId;
    }

    public void setBookId(long bookId) {
        _bookId = bookId;
    }

    public String getName() {
        return _name;
    }

    public void setName(String name) {
        _name = name;
    }
}

AuthorFormController.java

    @Controller
    @RequestMapping("/author")
    public class AuthorFormController {

        @InitBinder("authorCommandObject")
        public void initBinder(WebDataBinder binder) {
            binder.setValidator(new AutherCommandObjectValidator(new AuthorValidator(), new BookValidator()));      
        }

        @RequestMapping(method=RequestMethod.GET, value ="/create", produces = "text/html")
        public String createForm(Model model) {
            AuthorCommandObject authorCommandObject = new AuthorCommandObject();
            authorCommandObject.setAuthor(new Author());
            authorCommandObject.setBook(new Book());
            model.addAttribute("authorCommandObject", authorCommandObject);
            return "/author/create";
        }

        @RequestMapping(method=RequestMethod.POST, value ="/save", produces = "text/html")
        public String save(@Valid @ModelAttribute("authorCommandObject") AuthorCommandObject authorCommandObject, BindingResult result, Model model) {


        if (result.hasErrors()) {
            return "/author/create";
        }

        // the rest of the logic here

        }
    }

create.html

    <form th:action="@{/author/save}" method="POST" class="form-horizontal" th:object="${authorCommandObject}">
        Author Name:<input type="text" th:field="*{author.name}" />
        <ul th:if="${#fields.hasErrors('author.name')}">
            <li th:each="err : ${#fields.errors('author.name')}" th:text="${err}" />
        </ul>
        <input type="submit" value="Submit" class="btn btn-primary btn-lg" />
    </form>

AuthorCommandObjectValidator.java

public class AuthorCommandObjectValidator implements Validator {

    private final Validator _authorValidator;
    private final Validator _bookValidator;

    public AuthorCommandObjectValidator(Validator authorValidator, Validator bookValidator) {
        _authorValidator = authorValidator;
        _bookValidator = bookValidator;
    }

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

    @Override
    public void validate(Object obj, Errors errors) {
        AuthorCommandObject authorCommandObject = (AuthorCommandObject)obj; 
        try {
            errors.pushNestedPath("author");
            ValidationUtils.invokeValidator(_authorValidator, authorCommandObject.getAuthor(), errors);

            errors.pushNestedPath("book");
            ValidationUtils.invokeValidator(_bookValidator, authorCommandObject.getBook(), errors);
        } finally {
            errors.popNestedPath();
        }
    }
}

AuthorValidator.java

public class AuthorValidator implements Validator {
    @Override
    public boolean supports(Class<?> clazz) {
        return Author.class.equals(clazz);
    }

    @Override
    public void validate(Object obj, Errors errors) {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "field.required");
    }
}

Частичная Stacktrace (последняя строка является наиболее полезной)

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "#fields.hasErrors('author.name')"
org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "#fields.hasErrors('author.name')"
org.springframework.beans.NotReadablePropertyException: Invalid property 'author.author' of bean class [com.sample.application.AuthorCommandObject]: Bean property 'author.author' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
  • 0
    пост геттеры и сеттеры здесь тоже, это может быть проблемой
  • 0
    Я думаю, что вы должны оценивать # fields.hasErrors ('name'), потому что вы находитесь "внутри" формы, которая имеет th: object = "$ {authorCommandObject}", поэтому оценка выражений находится в поиске автора свойства в объекте формы, который сам автор?
Показать ещё 1 комментарий
Теги:
spring-mvc
thymeleaf

1 ответ

0

Тебе нужен такой тег раньше:

<div th:object="${form}" th:remove="tag"> <ul> <li th:each="err: ${#fields.errors('*')}" th:text="${err}"/> </ul> </div>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню