Ни BindingResult, ни простой целевой объект для имени компонента xxx не доступны в качестве атрибута запроса - PullRequest
0 голосов
/ 28 ноября 2018

"Ни BindingResult, ни простой целевой объект для имени компонента 'loginCommand' не доступны в качестве атрибута запроса"

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

Это первый контроллер моего нового проекта, и у меня возникли некоторые проблемы с получением xml.Я думаю, что это все исправлено, но если ничего не сработает, я предположил, что проблема может быть там.Странно то, что весь этот код почти полностью скопирован из другого проекта, который у меня есть, и он прекрасно работает.

Также я бегу на стеклянной рыбе, если это вообще имеет значение.Заранее спасибо!

edit: веб-страница /morencore/login.jsp.Я попытался зайти в login.html, предполагая, что это вызовет его, но, похоже, он работает только тогда, когда я захожу в login.jsp.Я полагаю, что я попытался изменить свой контроллер для сопоставления с jsp, но это не сработало.

вот моя страница login.jsp:

<form:form method="post" modelAttribute="loginCommand">

    <form:errors cssClass="error" element="p" />

    <table border="0">
        <tr>
            <td align="right">Username:</td>
            <td><form:input path="userName" /> <form:errors path="userName" cssClass="error" /></td>
        </tr>
        <tr>
            <td align="right">Password:</td>
            <td><form:password path="password" /> <form:errors path="password" cssClass="error" /></td>
        </tr>
        <tr>
            <td colspan="2" align="center"><input type="submit" id="submit" name="submit" value="Log In" disabled="disabled"></td>
        </tr>
    </table>

</form:form>

и вот мой контроллер:

@Controller
@ControllerAdvice
@RequestMapping("/login.html")
public class LoginController {

    protected final Logger logger = LogManager.getLogger(getClass());

    @Autowired
    protected LoginValidator loginValidator;

    @RequestMapping(method= RequestMethod.GET)
    protected String initializeForm(@ModelAttribute("loginCommand")LoginCommand loginCommand,
                                    BindingResult result,
                                    ModelMap model)
    {
        logger.info("INITIALIZING LOGIN FORM");
        model.addAttribute("loginCommand", new LoginCommand());
        return "login";
    }

    @InitBinder("loginCommand")
    protected void initBinder(ServletRequestDataBinder binder) throws Exception
    {
        binder.addValidators(loginValidator);
    }

    @RequestMapping(method=RequestMethod.POST)
    protected String onSubmit(@ModelAttribute("loginCommand")LoginCommand loginCommand,
                              BindingResult result,
                              HttpServletRequest request) throws Exception
    {
        logger.info("validating login input");
        loginValidator.validate(loginCommand, result);

        if (result.hasErrors())
        {
            result.reject("login.failure");
            return "login";
        }
        UserDao userDao = new UserDao();
        User user = userDao.by_name(loginCommand.getUserName());
        if (user == null
                || !user.getName().equals(loginCommand.getUserName())
                || !user.getPassword().equals(loginCommand.getPassword()))
        {
            result.reject("login.failure");
            return "login";
        }
        return "redirect:main.html";
    }
}

Вот мой класс LoginCommand:

@XmlRootElement
public class LoginCommand
{
    private String userName;
    private String password;

    /** blah blah blah getters and setters*/
}

Вот полная трассировка стека согласно запросу:

Neither BindingResult nor plain target object for bean name 'loginCommand' available as request attribute
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'loginCommand' available as request attribute
        at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:142)
        at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:168)
        at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:188)
        at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:154)
        at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.autogenerateId(AbstractDataBoundFormElementTag.java:141)
        at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.resolveId(AbstractDataBoundFormElementTag.java:132)
        at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:116)
        at org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:422)
        at org.springframework.web.servlet.tags.form.InputTag.writeTagContent(InputTag.java:142)
        at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)
        at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:80)
        at org.apache.jsp.login_jsp._jspx_meth_form_input_0(login_jsp.java:233)
        at org.apache.jsp.login_jsp._jspService(login_jsp.java:126)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:411)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:473)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:377)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)
        at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1580)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:338)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.glassfish.tyrus.servlet.TyrusServletFilter.doFilter(TyrusServletFilter.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:250)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:652)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:591)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
        at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
        at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:463)
        at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:168)
        at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
        at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
        at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:242)
        at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
        at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
        at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539)
        at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)

1 Ответ

0 голосов
/ 29 ноября 2018

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

@Controller
public class LoginController {

    protected final Logger logger = LogManager.getLogger(getClass());  //look at SLF4J instead.  Then you're not tied to a specific logger and you use a facade.

    @Autowired //may want to use constructor wiring instead on these
    private LoginValidator loginValidator;

    @Autowired
    private UserDao userDao; //this should be wired and not simply instantiated - Spring won't know about it otherwise

    @Autowired
    private LoginValidator loginValidator;

    @GetMapping("/login")
    public String initializeForm(Model model) {
        logger.info("INITIALIZING LOGIN FORM");
        model.addAttribute("loginCommand", new LoginCommand());
        return "login";
    }

    @PostMapping("/loginPost")
    public String onSubmit(@ModelAttribute("loginCommand") LoginCommand loginCommand,
                            BindingResult result) throws Exception {

        logger.info("validating login input");
        loginValidator.validate(loginCommand, result);

        if (result.hasErrors()) {
            result.reject("login.failure");
            return "login";
        }

        User user = userDao.by_name(loginCommand.getUserName());
        if (user == null
                || !user.getName().equals(loginCommand.getUserName())
                || !user.getPassword().equals(loginCommand.getPassword())) { //you should really refactor this and move it outside of your controller.  Just keep routing code in your controller, not logic

            result.reject("login.failure");
            return "login";
        }
        return "main"; //you should return just "main" or redirect:/main depending on what you're trying to do - you want the JSP to be processed.  Leaving off the extension allows you to change frameworks without changing the server-side code and allows the page to be compiled.  You could switch to Thymeleaf, for example, and not touch any of this code.
    }
}

Добавьте действие в вашу форму:

<form:errors cssClass="error" element="p" />

<table border="0">
    <tr>
        <td align="right">Username:</td>
        <td><form:input path="userName" /> <form:errors path="userName" cssClass="error" /></td>
    </tr>
    <tr>
        <td align="right">Password:</td>
        <td><form:password path="password" /> <form:errors path="password" cssClass="error" /></td>
    </tr>
    <tr>
        <td colspan="2" align="center"><input type="submit" id="submit" name="submit" value="Log In"></td>
    </tr>
</table>

Для следующего разработчика, читающего ваш код, я бы переименовал LoginCommand в нечто более близкое к тому, что есть на самом деле - например, UserDetailsAdapter или что-то в этом роде.Я предполагаю, что LoginCommand будет реализовывать UserDetails из Spring Security, если вы используете это.

Вы также можете рассмотреть вопрос об обновлении UserDao, чтобы метод вызывался findOneByUsername вместо by_name.Соглашение об именах может помочь вам позже, когда вы используете репозитории Spring.

Наконец, посмотрите на Project Lombok для ваших bean-компонентов.Это избавит вас от головной боли.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...