Недопустимая цель для ошибки весны валидатора?

#java #spring #jsp

#java #весна #jsp

Вопрос:

Я получаю следующую ошибку всякий раз, когда пытаюсь получить доступ к URL-адресу «/ shows» онлайн:

 java.lang.IllegalStateException: Invalid target for Validator [co2103.hw1.controller.ShowValidator@7f9fc01d]: co2103.hw1.domain.Channel@72edafb5
  

В коде нет ничего сложного, просто я не понимаю, что происходит не так, и надеялся, что вы, ребята, сможете помочь. Весь код работает нормально, пока я не реализую валидатор для класса Show

Контроллер

 @Controller
public class ShowController {
    
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.addValidators(new ShowValidator());
    }
    
    @GetMapping("/shows")
    public String listShows(@RequestParam(name = "channel") int passedID, Model model) {
        
        Channel channel = new Channel();
        List<Channel> channels = Hw1Application.channels;
        for (Channel ch : channels) {
            if (ch.getId() == passedID) {
                channel = ch;
            }
        }
        
        List<Show> shows = channel.getShows();
        model.addAttribute("channel", channel);
        model.addAttribute("shows", shows);
        
        return "/shows/list";
    }
    
    @RequestMapping("/newShow")
    public String goToAddShowForm(@RequestParam(name = "channel") int passedID, Model model) {
        
        Channel channel = new Channel();
        List<Channel> channels = Hw1Application.channels;
        for (Channel ch : channels) {
            if (ch.getId() == passedID) {
                channel = ch;
            }
        }
        Show show = new Show();
        
        model.addAttribute("show", show);
        model.addAttribute("channel", channel);
        
        return "/shows/form";
    }
    
    @PostMapping("addShow")
    public String addShow(@Valid @ModelAttribute Show show, BindingResult result, @RequestParam(name = "channel") int passedID) {
        
        if (result.hasErrors()) {
            return "/show/form";
        }
        
        Channel channel = null;
        for (Channel ch : Hw1Application.channels) {
            if (ch.getId() == passedID) {
                channel = ch;
                break;
            }
        }
        
        List<Show> shows = channel.getShows();
        shows.add(show);
        channel.setShows(shows);
        
        return "redirect:/channels";
    }

}
  

Валидатор

 public class ShowValidator implements Validator {

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

    @Override
    public void validate(Object target, Errors errors) {
        
        Show show = (Show) target;
        
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "title", "", "Title cannot be empty!");
        
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "actors", "", "Actors cannot be empty!");
        
        List<String> validCategories = new ArrayList<>();
        validCategories.addAll(Arrays.asList("Comedy", "Documentary", "Drama"));
        
        if (!validCategories.contains(show.getCategory())) {
            errors.rejectValue("category", "", "Category must be either 'Comedy', 'Drama' or 'Documentary'");
        }
        
        if (show.getEpisodes() <= 4 || show.getEpisodes() > 8) {
            errors.rejectValue("episodes", "", "Episodes must be between (including) 5 and 8");
        }

    }

}
  

Jsp

 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h2>Add new show for ${channel.name}</h2>

    <form:form action = "addShow?channel=${channel.id}" modelAttribute = "show">
        
        <form:label path = "title">Title of show </form:label><form:input path = "title"/>
        <form:errors path = "title"/><br/>
        
        <form:label path = "actors">Actors in show </form:label><form:input path = "actors"/>
        <form:errors path = "actors"/><br/>
        
        <form:label path = "category">Show category </form:label><form:input path = "category"/>
        <form:errors path = "category"/><br/>
        
        <form:label path = "episodes">How many episodes? ></form:label><form:input path = "episodes"/>
        <form:errors path = "episodes"/><br/>
        
        <input type = "submit">
        
    </form:form>
    
</body>
</html>
  

Впервые публикую здесь, и я не особенно часто посещаю сайт, поэтому извините, если мое форматирование отключено.

Ответ №1:

Укажите параметр value для аннотации @InitBinder:

 @InitBinder("show")
  

Подробности см. В документации по типу аннотации InitBinder:

По умолчанию применяется ко всем атрибутам команды / формы и ко всем параметрам запроса, обрабатываемым аннотированным классом обработчика. Указание имен атрибутов модели или имен параметров запроса здесь ограничивает метод init-binder этими конкретными атрибутами / параметрами, при этом разные методы init-binder обычно применяются к разным группам атрибутов или параметров.