Я сталкиваюсь с этим странным поведением, когда Spring MVC и JSP, где ModelAttribute
отправляется на JSP с заполненными полями, но когда он возвращается в контроллер, все поля null
.
Итак, прежде всего я поместил объект как атрибут в модель.
@PostMapping("qcm")
public String qcm(@ModelAttribute("qcm") Qcm formQcm, Model model) {
Qcm q = props.getQcm(formQcm.getDomaine(), formQcm.getMode());
model.addAttribute("qcm", q);
this.qcm = q;
return "qcm";
}
Атрибут ModelAttribute здесь работает просто отлично. Но обратите внимание, что здесь я добавляю новый атрибут в модель.
На странице qcm.jsp
я отображаю форму с некоторой информацией из объекта qcm
, который я поместил в модель ранее. Это означает, что я не могу отправить поля qcm
как null
.
Вот qcm.jsp
:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
<div class="container">
<h1 class="h3 mb-3 font-weight-normal">QCM</h1>
<form:form action="sendqcm" modelAttribute="qcm" method="POST">
<c:forEach var="question" items="${qcm.questions}">
<p>${question.data}?</p>
<c:forEach var="reponse" items="${question.reponses}">
<div class="form-check form-check-inline">
<form:radiobutton path="${question.chosenReponse}" value="${reponse}" label="${reponse.data}" class="form-check-input"/>
</div>
</c:forEach>
</c:forEach>
<input type="submit" value="envoyer" class="save" class="btn btn-lg btn-primary btn-block"/>
</form:form>
</div>
</body>
</html>
Информация отображается очень хорошо , Я сопоставил action
с sendqcm
контроллером. Вот оно:
@PostMapping("sendqcm")
public String sendqcm(@ModelAttribute("qcm") Qcm formQcm, Model model) {
System.out.println("Domaine -> " + formQcm.getDomaine());
System.out.println("Mode -> " + formQcm.getMode());
for(Question q : formQcm.getQuestions()) {
System.out.println(q.getChosenReponse());
}
for (Question q : formQcm.getQuestions()) {
if (q.answeredCorrectly())
score++;
}
model.addAttribute("score", score);
return "reponses";
}
Две строки System.out.println()
возвращают ноль, а затем программа завершается с ошибкой NullPointerException
:
java.lang.NullPointerException
at fr.insa.controller.AppController.sendqcm(AppController.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:660)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:808)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)