Can't generate html page into pdf with wkhtmltopdf in spring - spring

In my recent spring project, I need to generate a pdf file from html page. I am trying to do this task with WkhtmlToPdf. But i am unable to generate pdf file from html page. I search many project and tutorial about WkhtmlToPdf but I didn't find any answer. I am posting my code here.
This is my Controller class that redirect to html page with student list
#Controller
public class TestController {
#Autowired
StudentService studentService;
#Autowired
PdfDemo pdfDemo;
#GetMapping("/test")
private String testPage(Model model)
{
List<Student> studentList = studentService.findAll();
System.out.println(studentList);
model.addAttribute(studentList);
return "sample";
}
}
This is my html page that show list of student
<body>
<div class="container" id="pdfDiv">
<h2>HTML Table</h2>
<table class="table table-striped">
<tr>
<th>Id</th>
<th>Name</th>
<th>Session</th>
<th>Department</th>
<th>Roll</th>
<th>Mobile</th>
</tr>
<tr th:each="student : ${studentList}">
<td th:text="${student.id}"></td>
<td th:text="${student.name}"></td>
<td th:text="${student.session}"></td>
<td th:text="${student.department}"></td>
<td th:text="${student.roll}"></td>
<td th:text="${student.mobile}"></td>
</tr>
</table>
</div>
Download PDF
</body>
Here you can see, I have a link to generate pdf. The PdfGenerateController class is
#Controller
public class PdfGenerateController {
#GetMapping("/getStudentsListAsPdf")
public ResponseEntity<Resource> generateReportOfStudent() {
String downloadFilePath = generatePdfListForStudents();
System.out.println("DL File Path: "+downloadFilePath);
if (downloadFilePath == null)
throw new NullPointerException("data missing");
if (downloadFilePath == null)
return ResponseEntity.badRequest()
.contentType(MediaType.parseMediaType("application/pdf"))
.body(null);
File file = new File(downloadFilePath);
Path path = Paths.get(file.getAbsolutePath());
ByteArrayResource resource = null;
try {
resource = new ByteArrayResource(Files.readAllBytes(path));
} catch (IOException e) {
e.printStackTrace();
}
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment; filename=\"student_list" + ".pdf\"");
return ResponseEntity.ok()
.headers(headers)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/pdf"))
.body(resource);
}
}
And this is the class where code are written to generate pdf
#Service
public class PdfDemo {
#Value("${file.download.base}")
private String DOWNLOAD_FOLDER;
public static final String DOWNLOAD_PATH = "tmp/downloads/";
public static final String ZIP_PATH = "/tmp/zip_files";
public static final String FILE_NAME = "student_list";
public static final String SERVER_REPORT_URL = "/report/html";
public static final String DOWNLOAD_FILE_PATH = DOWNLOAD_PATH + FILE_NAME;
public static final String ZIPFILE = "/tmp/zip_files/cmed_report.zip";
public static final String ZIPFILE_NAME = "cmed_report.zip";
public static final String SRCDIR = "/tmp/downloads";
public static final String DATE_FORMAT_PATTERN = "yyyy-MM-dd-HH";
public static String getBaseURL() throws MalformedURLException {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes()).getRequest();
String baseUrl = "";
if (request != null) {
// handle proxy forward
String scheme = request.getScheme();
if (request.getHeader("x-forwarded-proto") != null) {
scheme = request.getHeader("x-forwarded-proto");
}
Integer serverPort = request.getServerPort();
if ((serverPort == 80) || (serverPort == 443)) {
// No need to add the server port for standard HTTP and HTTPS ports, the scheme will help determine it.
baseUrl = String.format("%s://%s%s", scheme, request.getServerName(), request.getContextPath());
} else {
baseUrl = String.format("%s://%s:%d%s", scheme, request.getServerName(), serverPort, request.getContextPath());
}
}
return baseUrl;
}
public static String generatePdfListForStudents()
{
WkHtmlToPdf pdf = new WkHtmlToPdf();
try {
pdf.addSources(Source.fromUrl(getServerAbsolutePath(SERVER_REPORT_URL)));
System.out.println("Server absolute path: " + getServerAbsolutePath(SERVER_REPORT_URL));
System.out.println(Source.fromUrl(getServerAbsolutePath(SERVER_REPORT_URL)));
} catch (Exception e) {
e.printStackTrace();
}
String downloadPath = DOWNLOAD_FILE_PATH + ".pdf";
pdf.addArguments(
Argument.from(EnableJavascript));
System.out.println("PDF Location: " + downloadPath);
// Save the PDF
File file = new File(downloadPath);
System.out.println("Directory status: " + file.exists() + " " + file.isDirectory());
try {
System.out.println("Paths.get: " + Paths.get(downloadPath));
pdf.save(Paths.get(downloadPath));
} catch (IOException e) {
e.printStackTrace();
}
return downloadPath;
}
public static String getServerAbsolutePath(String requestPath) throws MalformedURLException {
String URL = getBaseURL() + requestPath;
return URL;
}
}
And this is the Controller class for SERVER_REPORT_URL in PdfDemo class
#Controller
public class HtmlViewReportController {
#Autowired
StudentService studentService;
#GetMapping(value = "/report/html")
public String getPdfReportForStudent(Model model) {
model.addAttribute("studentList", studentService.findAll());
return "sample";
}
}
Now, When I hit on Download PDFin html page I get error. Error stack trace here
java.io.IOException: Cannot run program "wkhtmltopdf": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at java.lang.Runtime.exec(Runtime.java:620)
at java.lang.Runtime.exec(Runtime.java:528)
at com.ztomic.wkhtmltopdf.WkHtmlToPdf.convert(WkHtmlToPdf.java:84)
at com.ztomic.wkhtmltopdf.WkHtmlToPdf.getPdfBytes(WkHtmlToPdf.java:77)
at com.ztomic.wkhtmltopdf.WkHtmlToPdf.save(WkHtmlToPdf.java:68)
at com.avijit.test.PdfUtil.PdfDemo.generatePdfListForStudents(PdfDemo.java:109)
at com.avijit.test.Controller.PdfGenerateController.generateReportOfStudent(PdfGenerateController.java:28)
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:209)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
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:877)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
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.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:155)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:123)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:108)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
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:198)
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:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
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)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 71 more
DL File Path: tmp/downloads/student_list.pdf
java.nio.file.NoSuchFileException: /home/dracula/IdeaProjects/WkhtmlToPdfGeneratorProject/tmp/downloads/student_list.pdf
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)
at java.nio.file.Files.newByteChannel(Files.java:361)
at java.nio.file.Files.newByteChannel(Files.java:407)
at java.nio.file.Files.readAllBytes(Files.java:3152)
at com.avijit.test.Controller.PdfGenerateController.generateReportOfStudent(PdfGenerateController.java:43)
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:209)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
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:877)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
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.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:155)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:123)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:108)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
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:198)
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:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
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)
Here the github link. It will be very helpful if any one can solve this.

Did you install wkhtmltopdf in your machine ? try it on https://wkhtmltopdf.org/downloads.html
I did it in a simpler way using Pdf Object from
import com.github.jhonnymertz.wkhtmltopdf.wrapper.Pdf;
The generation of pdf looks easier as follows:
#Override
public String save(String url) throws IOException, InterruptedException{
Pdf pdf = new Pdf();
pdf.addPageFromUrl(url);
return mockSaveS3(pdf);
}
private String mockSaveS3(Pdf pdf) throws IOException, InterruptedException{
File fileTemp = File.createTempFile("pdf-", "");
File file = pdf.saveAs("apps/" + fileTemp.getName());
return file.getAbsolutePath();
}
And I returned the Url to the PDF that I stored in apps/ directory.

I solved this problem. It took a long time to solve. I wrote a blog step by step in the medium. Here I am posting that link. You can see all the steps here. I also provided github link of sample project. Look
here

Related

Zuul Forwarding Exception caused by org.apache.http.NoHttpResponseException: The target server failed to respond

Hello Stack Overflow Community,
Been a while since I've asked a question so if I forget some information, just let me know and I will gladly add.
We have recently uncovered some issues occurring in our client-server. We are running a Spring server that handles client requests and renders HTML via Thymeleaf. We are using Zuul as a way to redirect our many client routes to a single Spring endpoint that serves up a single bundle so that no matter where a user refreshes, they will receive the bundle we want them to get. This seems to work most of the time but once every minute or so (out of thousands a minute) we get a zuul forwarding exception like so:
[2m2020-11-30 02:26:51.023[0;39m [33m WARN[0;39m [35m50[0;39m [2m---[0;39m [33m[trace=,span=][0;39m [2m[nio-8080-exec-2][0;39m [36mo.s.c.n.z.filters.post.SendErrorFilter [0;39m
[2m:[0;39m Error during filteringcom.netflix.zuul.exception.ZuulException: Forwarding error
 at
org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter.handleException(SimpleHostRoutingFilter.java:261) ~[spring-cloud-netflix-zuul-2.2.1.RELEASE.jar:2.2.1.RELEASE]
 at
org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter.run(SimpleHostRoutingFilter.java:241) ~[spring-cloud-netflix-zuul-2.2.1.RELEASE.jar:2.2.1.RELEASE]
 at
com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:117) ~[zuul-core-1.3.1.jar:1.3.1]
 at
com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:193) ~[zuul-core-1.3.1.jar:1.3.1]
at com.netflix.zuul.FilterProcessor.runFilters(FilterProcessor.java:157) ~[zuul-core-1.3.1.jar:1.3.1]
 at
com.netflix.zuul.FilterProcessor.route(FilterProcessor.java:118) ~[zuul-core-1.3.1.jar:1.3.1]
 at
com.netflix.zuul.ZuulRunner.route(ZuulRunner.java:96) ~[zuul-core-1.3.1.jar:1.3.1]
 at
com.netflix.zuul.http.ZuulServlet.route(ZuulServlet.java:116) ~[zuul-core-1.3.1.jar:1.3.1]
 at
com.netflix.zuul.http.ZuulServlet.service(ZuulServlet.java:81) ~[zuul-core-1.3.1.jar:1.3.1]
 at
org.springframework.web.servlet.mvc.ServletWrappingController.handleRequestInternal(ServletWrappingController.java:166) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.cloud.netflix.zuul.web.ZuulController.handleRequest(ZuulController.java:45) [spring-cloud-netflix-zuul-2.2.1.RELEASE.jar:2.2.1.RELEASE]
 at
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) [tomcat-embed-core-9.0.37.jar:4.0.FR]
 at
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) [tomcat-embed-core-9.0.37.jar:4.0.FR]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-embed-websocket-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.springframework.web.servlet.resource.ResourceUrlEncodingFilter.doFilter(ResourceUrlEncodingFilter.java:64) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:109) [spring-boot-actuator-2.2.7.RELEASE.jar:2.2.7.RELEASE]
 at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.cloudfoundry.router.ClientCertificateMapper.doFilter(ClientCertificateMapper.java:79) [client_certificate_mapper-1.11.0_RELEASE.jar:na]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:747) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_242]
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_242]
 at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at java.lang.Thread.run(Thread.java:748) [na:1.8.0_242]

Caused by: org.apache.http.NoHttpResponseException: The target server failed to respond
 at
org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:141) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259) ~[httpcore-4.4.13.jar:4.4.13]
 at
org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163) ~[httpcore-4.4.13.jar:4.4.13]
 at
org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273) ~[httpcore-4.4.13.jar:4.4.13]
 at
org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125) ~[httpcore-4.4.13.jar:4.4.13]
 at
org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:118) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter.forwardRequest(SimpleHostRoutingFilter.java:422) ~[spring-cloud-netflix-zuul-2.2.1.RELEASE.jar:2.2.1.RELEASE]
 at
org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter.forward(SimpleHostRoutingFilter.java:341) ~[spring-cloud-netflix-zuul-2.2.1.RELEASE.jar:2.2.1.RELEASE]
 at
org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter.run(SimpleHostRoutingFilter.java:236) ~[spring-cloud-netflix-zuul-2.2.1.RELEASE.jar:2.2.1.RELEASE]
 ... 61 common frames omitted
As you can see, we are using HttpClient 4.5.12. I saw similar issues occurring in 4.4 in this post but we upgraded and the issue persisted. In the same post #daimarom commented that perhaps the PoolingHttpClientConnectionManager could be causing an issue. This is how we configured our pool manager:
#Bean
public PoolingHttpClientConnectionManager connectionManager() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setValidateAfterInactivity(5000);
connectionManager.setDefaultMaxPerRoute(40);
connectionManager.setMaxTotal(15);
return connectionManager;
}
#Bean
public CloseableHttpClient httpClient() throws Exception {
return HttpClients.custom()
.disableAutomaticRetries()
.setSSLContext(sslContext())
.setSSLSocketFactory(socketFactory())
.setConnectionManager(connectionManager())
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
}
Playing aroung with the connection manager parameters did not help.
We had a Zuul filter but made our routing completely configuration based to rule out any logical errors. Currently our Zuul configuration looks like such:
zuul:
sensitive-headers:
host.socket-timeout-millis: 60000
routes:
api:
strip-prefix: false
path: /api/**
url: "${validation.urls.piserver}"
extract:
strip-prefix: true
path: /web2/extract/**
url: "${validation.urls.piclient}/validate"
legal:
strip-prefix: true
path: /web2/legal/**
url: "${validation.urls.piclient}/validate"
capture-vin:
strip-prefix: true
path: /web2/capture-instructions/vin/**
url: "${validation.urls.piclient}/validate"
recapture-vin:
strip-prefix: true
path: /web2/recapture-instructions/vin/**
url: "${validation.urls.piclient}/validate"
capture-odometer:
strip-prefix: true
path: /web2/capture-instructions/odometer/**
url: "${validation.urls.piclient}/validate"
recapture-odometer:
strip-prefix: true
path: /web2/recapture-instructions/odometer/**
url: "${validation.urls.piclient}/validate"
capture-rear:
strip-prefix: true
path: /web2/capture-instructions/rear/**
url: "${validation.urls.piclient}/validate"
recapture-rear:
strip-prefix: true
path: /web2/recapture-instructions/rear/**
url: "${validation.urls.piclient}/validate"
capture-rear-passenger:
strip-prefix: true
path: /web2/capture-instructions/rear-passenger/**
url: "${validation.urls.piclient}/validate"
recapture-rear-passenger:
strip-prefix: true
path: /web2/recapture-instructions/rear-passenger/**
url: "${validation.urls.piclient}/validate"
capture-front-passenger:
strip-prefix: true
path: /web2/capture-instructions/front-passenger/**
url: "${validation.urls.piclient}/validate"
recapture-front-passenger:
strip-prefix: true
path: /web2/recapture-instructions/front-passenger/**
url: "${validation.urls.piclient}/validate"
capture-front-driver:
strip-prefix: true
path: /web2/capture-instructions/front-driver/**
url: "${validation.urls.piclient}/validate"
recapture-front-driver:
strip-prefix: true
path: /web2/recapture-instructions/front-driver/**
url: "${validation.urls.piclient}/validate"
capture-rear-driver:
strip-prefix: true
path: /web2/capture-instructions/rear-driver/**
url: "${validation.urls.piclient}/validate"
recapture-rear-driver:
strip-prefix: true
path: /web2/recapture-instructions/rear-driver/**
url: "${validation.urls.piclient}/validate"
capture-damage-left:
strip-prefix: true
path: /web2/capture-instructions/damage-left/**
url: "${validation.urls.piclient}/validate"
recapture-damage-left:
strip-prefix: true
path: /web2/recapture-instructions/damage-left/**
url: "${validation.urls.piclient}/validate"
capture-damage-center:
strip-prefix: true
path: /web2/damage-capture-instructions/damage-center/**
url: "${validation.urls.piclient}/validate"
recapture-damage-center:
strip-prefix: true
path: /web2/damage-recapture-instructions/damage-center/**
url: "${validation.urls.piclient}/validate"
capture-damage-right:
strip-prefix: true
path: /web2/damage-capture-instructions/damage-right/**
url: "${validation.urls.piclient}/validate"
recapture-damage-right:
strip-prefix: true
path: /web2/damage-recapture-instructions/damage-right/**
url: "${validation.urls.piclient}/validate"
capture-damages:
strip-prefix: true
path: /web2/capture-instructions/damages/**
url: "${validation.urls.piclient}/validate"
recapture-damages:
strip-prefix: true
path: /web2/recapture-instructions/damages/**
url: "${validation.urls.piclient}/validate"
uploading:
strip-prefix: true
path: /web2/uploading/**
url: "${validation.urls.piclient}/validate"
submit:
strip-prefix: true
path: /submit/**
url: "${validation.urls.piclient}/validate"
intake-processing:
strip-prefix: true
path: /intake-processing/**
url: "${validation.urls.piclient}/validate"
already-submitted:
strip-prefix: true
path: /already-submitted/**
url: "${validation.urls.piclient}/validate"
submit-v1:
strip-prefix: true
path: /submit
url: "${validation.urls.piclient}/validate"
intake-processing-v1:
strip-prefix: true
path: /intake-processing
url: "${validation.urls.piclient}/validate"
already-submitted-v1:
strip-prefix: true
path: /already-submitted
url: "${validation.urls.piclient}/validate"
This used to be much more succinct in the routing filter when we simply reset the request URI in the current context but as I mentioned before, now this is all configuration based.
All of our dependencies are defined here:
dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
implementation 'org.yaml:snakeyaml:1.26'
implementation 'io.github.openfeign:feign-httpclient:10.7.4'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-zuul'
implementation 'org.apache.tomcat.embed:tomcat-embed-core:9.0.37'
implementation 'org.apache.tomcat.embed:tomcat-embed-el:9.0.37'
implementation 'org.apache.tomcat.embed:tomcat-embed-websocket:9.0.37'
implementation 'org.springframework.cloud:spring-cloud-cloudfoundry-connector'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
I feel like I am missing something completely obvious here but our manager who was very experienced with Zuul recently left. Please let me know if there is any additional information I can add here. Thank you in advance for any help.
[UPDATE]
I have recently attempted taking the entire pool manager out of the configuration. The problem has persisted. Now the configuration for the HttpClient looks like the following:
#Bean
public CloseableHttpClient httpClient() throws Exception {
return HttpClients.custom()
.disableAutomaticRetries()
.setSSLContext(sslContext())
.setSSLSocketFactory(socketFactory())
// .setConnectionManager(connectionManager())
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
}
Also, we tried with and without a spring security configuration chain explicitly defined. Nothing helped.
Ok so #brijesh mentioned a potential solution in the comments that I have yet to try but I did end up deploying another "fixing" change. It's more of a recovery from the issue which is mostly likely still occurring. I simply enabled automatic retrying by commenting out the following line:
#Bean
public CloseableHttpClient httpClient() throws Exception {
return HttpClients.custom()
// .disableAutomaticRetries()
.setSSLContext(sslContext())
.setSSLSocketFactory(socketFactory())
.setConnectionManager(connectionManager())
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
}
For anyone who does not explicitly configure their HttpClient settings, this shouldn't be an issue since the default is to retry 3 times.
For people who do configure these settings and are having issues with the connection manager, I will soon attempt #brijesh's approach (with automatic retrying disabled) to see if the solution resolves the root cause. I will update the answer here once I've completed this.

Create form dynamically using thymeleaf

I am new in Spring MVC. I'm stuck for more than 24hrs trying to add a dynamic row using thymeleaf. I followed this link and also the thymeleaf documentation In this tutorial but i have not been able to make it work. Clicking addRow and removeRow doesn't work. Someone should please help me. Thanks
Here is my Controller code:
#Controller
#SessionAttributes("qualification")
public class QualificationController {
private final QualificationService qualificationService;
private final StaffService staffService;
private final CourseService courseService;
#Autowired
public QualificationController(QualificationService qualificationService,
StaffQualificationService service,
StaffService staffService, CourseService courseService) {
this.qualificationService = qualificationService;
this.staffService = staffService;
this.courseService = courseService;
}
#InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
}
#GetMapping("/staff/{id}/qualification")
public String initForm(#PathVariable("id") Integer id, Model model) {
Staff staff = staffService.findById(id);
staff.addQualification(new StaffQualification());
model.addAttribute("qualification", staff);
model.addAttribute("qualifications", qualificationService.findAll());
model.addAttribute("courses", courseService.findAll());
return "registration/qualification";
}
#PostMapping(path = "/staff/{id}/qualification/new", params = {"save"})
public String addQualification(#ModelAttribute("qualification")
#Valid Staff staff,
BindingResult result, RedirectAttributes attributes,
SessionStatus status) {
if (result.hasErrors()) {
return "registration/qualification";
}
staffService.save(staff);
attributes.addFlashAttribute("successMessage", "Qualification successfully saved");
status.setComplete();
return "registration/qualification";
}
#PostMapping(path = "/staff/{id}/qualification/new", params = {"addRow"})
public String addRow(final Staff staff, BindingResult result) {
staff.getQuals().add(new StaffQualification());
return "registration/qualification";
}
#PostMapping(params = "removeRow", path = {"/staff/{id}/qualification/new"})
public String removeRow(final Staff staff, final BindingResult result,
final HttpServletRequest request) {
final int rowId = Integer.parseInt(request.getParameter("removeRow"));
staff.removeQualification(staff.getQuals().remove(rowId));
return "registration/qualification";
}
}
My entities:
public class Staff extends NamedEntity {
#NotBlank(message = "First Name is blank")
private String firstName;
#NotBlank(message = "Last Name is blank")
private String lastName;
private String middleName;
#Digits(fraction = 0, integer = 10)
#NotBlank(message = "Please fill in your phone number")
private String phoneNumber;
private boolean married;
private String gender;
#Transient
private int age;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "staff", orphanRemoval = true)
private List<StaffQualification> quals = new ArrayList<>();
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "staff", orphanRemoval = true)
private List<Document> documents = new ArrayList<>();
}
public class StaffQualification extends BaseEntity {
private String qualification;
private String course;
private String school;
#NotNull(message = "Date obtained qualification must be in the past")
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private LocalDate qualDate;
#ManyToOne
private Staff staff;
}
Thymeleaf code:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Staff form</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css"
th:href="#{https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css}"
integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
</head>
<body>
<div class="justify-content-start">
<div th:include="fragments/bodyHeader.html"></div>
</div>
<div class="main body-content">
<div class="container">
<form th:object="${qualification}" th:action="#{/staff/{id}/qualification/new}" th:method="post">
<div class="alert alert-info" th:if="${successMessage}" th:utext="${successMessage}"></div>
<fieldset>
<legend class="w-auto" th:text="#{qualification.staff}">Staff Qualifications</legend>
<div>
<table id="items" class="table table-bordered">
<thead>
<tr>
<th th:scope="col">#</th>
<th th:scope="col">Title</th>
<th th:scope="col">Course</th>
<th th:scope="col">School</th>
<th th:scope="col" type="date">Date Obtained</th>
<th>
<button type="submit" name="addRow" th:text="#{qualification.row.add}">Add row</button>
</th>
</tr>
</thead>
<tbody id="tbodyContainer">
<tr th:each="row, rowStat : *{quals}">
<td th:text="${rowStat.count}">1</td>
<td>
<label>
<select th:field="*{quals[__${rowStat.index}__].qualification}">
<option th:each="var : ${qualifications}"
th:value="${var.id}"
th:text="${var.name}">
</option>
</select>
</label>
</td>
<td>
<label>
<select th:field="*{quals[__${rowStat.index}__].course}">
<option th:each="let : ${courses}"
th:value="${let.id}"
th:text="${let.name}">
</option>
</select>
</label>
</td>
<td>
<label>
<input type="text" th:field="*{quals[__${rowStat.index}__].school}"
th:errorClass="fieldError"/>
</label>
</td>
<td>
<label>
<input type="date" th:field="*{quals[__${rowStat.index}__].qualDate}"/>
</label>
</td>
<td>
<button type="submit" name="removeRow" th:value="${rowStat.index}"
th:text="#{qualification.row.remove}">Remove row
</button>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<button class="btn btn-primary" name="save" style="margin-right: 50px" type="submit">Save</button>
</div>
</fieldset>
<div class="form-actions row justify-content-center" style="padding-top:10px; padding-right: 200px">
<a th:if="${qualification.id}" href="/staff/{id}/qualification"
th:href="#{/staff/{id}/qualification/(id=${qualification.id})}"
class="btn btn-primary">Next</a>
</div>
</form>
</div>
</div>
</body>
</html>
Account Controller:
#Controller
#SessionAttributes("account")
public class AccountController {
private final PencomService pencomService;
private final StaffService staffService;
private final BankService bankService;
#Autowired
public AccountController(PencomService pencomService, StaffService staffService,
BankService bankService) {
this.pencomService = pencomService;
this.staffService = staffService;
this.bankService = bankService;
}
#InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
}
#GetMapping("/staff/{id}/account")
public String initCreationForm(#PathVariable("id") Integer staffId, Model model) {
Staff staff = staffService.findById(staffId);
staff.setBankAccount(new BankAccount());
staff.setPencomAccount(new PencomAccount());
model.addAttribute("account", staff);
model.addAttribute("listBanks", bankService.findAll());
model.addAttribute("listPensions", pencomService.findAll());
return "registration/account";
}
#PostMapping("/staff/{id}/account/new")
public String addAccount(#ModelAttribute("account") #Valid Staff staff,
BindingResult result, RedirectAttributes attributes, SessionStatus status) {
if (result.hasErrors()) {
return "registration/account";
} else {
staffService.save(staff);
attributes.addFlashAttribute("successMessage", "Accounts successfully saved");
status.setComplete();
return "/registration/account";
}
}
}
Error Message:
java.lang.NullPointerException: null
at com.chairmo.cadre.controller.AccountController.initCreationForm(AccountController.java:48) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

Failed parsing Thymeleaf template when validating form with Spring Bean Validation API

I am following this book "Spring In Action 5th Edition" example, but having this error whenever validation on form input found something invalid.
error:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Oct 27 17:26:07 SGT 2019
There was an unexpected error (type=Internal Server Error, status=500).
An error happened during template parsing (template: "class path resource [templates/design.html]")
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/design.html]")
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241)
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100)
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:666)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:362)
at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:189)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1371)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1117)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1056)
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:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
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:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
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:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
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)
Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "design" - line 59, col 20)
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393)
at org.attoparser.MarkupParser.parse(MarkupParser.java:257)
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230)
... 52 more
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "design" - line 59, col 20)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:117)
at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95)
at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)
at org.thymeleaf.engine.ProcessorTemplateHandler.handleStandaloneElement(ProcessorTemplateHandler.java:918)
at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleStandaloneElementEnd(TemplateHandlerAdapterMarkupHandler.java:260)
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleStandaloneElementEnd(InlinedOutputExpressionMarkupHandler.java:256)
at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleStandaloneElementEnd(OutputExpressionInlinePreProcessorHandler.java:169)
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleStandaloneElementEnd(InlinedOutputExpressionMarkupHandler.java:104)
at org.attoparser.HtmlElement.handleStandaloneElementEnd(HtmlElement.java:79)
at org.attoparser.HtmlMarkupHandler.handleStandaloneElementEnd(HtmlMarkupHandler.java:241)
at org.attoparser.MarkupEventProcessorHandler.handleStandaloneElementEnd(MarkupEventProcessorHandler.java:327)
at org.attoparser.ParsingElementMarkupUtil.parseStandaloneElement(ParsingElementMarkupUtil.java:96)
at org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:706)
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301)
... 54 more
Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'design' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:153)
at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:903)
at org.thymeleaf.spring5.context.webmvc.SpringWebMvcThymeleafRequestContext.getBindStatus(SpringWebMvcThymeleafRequestContext.java:227)
at org.thymeleaf.spring5.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:306)
at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:253)
at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:227)
at org.thymeleaf.spring5.processor.AbstractSpringFieldTagProcessor.doProcess(AbstractSpringFieldTagProcessor.java:174)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74)
... 67 more
Object been passed to view template:
package tacos;
import java.util.List;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import lombok.Data;
#Data
public class Taco {
#NotNull
#Size(min=5, message="Name must be at least 5 characters long")
private String name;
#NotNull
#Size(min=2, message="You must choose at least 2 ingredient")
private List<String> ingredients;
}
Thymeleaf view template:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Taco Cloud</title>
<link rel="stylesheet" th:href="#{/styles.css}" />
</head>
<body>
<h1>Design your taco!</h1>
<img th:src="#{/images/TacoCloud.png}"/>
<form method="POST" th:object="${design}">
<div class="grid">
<div class="ingredient-group" id="wraps">
<h3>Designate your wrap:</h3>
<div th:each="ingredient : ${wrap}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"
/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group" id="proteins">
<h3>Pick your protein:</h3>
<div th:each="ingredient : ${protein}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"
/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group" id="cheeses">
<h3>Choose your cheese:</h3>
<div th:each="ingredient : ${cheese}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"
/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group" id="veggies">
<h3>Determine your veggies:</h3>
<div th:each="ingredient : ${veggies}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"
/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group" id="sauces">
<h3>Select your sauce:</h3>
<div th:each="ingredient : ${sauce}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"
/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
</div>
<div>
<h3>Name your taco creation:</h3>
<input type="text" th:field="*{name}"/>
<span class="validationError"
th:if="${#fields.hasErrors('name')}"
th:errors="*{name}">Name Error</span>
<br/>
<button>Submit your taco</button>
</div>
</form>
</body>
</html>
Controller display form method:
#GetMapping
public String showDesignForm(Model model)
{
List<Ingredient> ingredients = Arrays.asList(
new Ingredient("FLTO", "Flour Tortilla", Type.WRAP),
new Ingredient("COTO", "Corn Tortilla", Type.WRAP),
new Ingredient("GRBF", "Ground Beef", Type.PROTEIN),
new Ingredient("CARN", "Carnitas", Type.PROTEIN),
new Ingredient("TMTO", "Diced Tomatoes", Type.VEGGIES),
new Ingredient("LETC", "Lettuce", Type.VEGGIES),
new Ingredient("CHED", "Cheddar", Type.CHEESE),
new Ingredient("JACK", "Monterrey Jack", Type.CHEESE),
new Ingredient("SLSA", "Salsa", Type.SAUCE),
new Ingredient("SRCR", "Sour Cream", Type.SAUCE)
);
Type[] types = Ingredient.Type.values();
for (Type type : types)
{
model.addAttribute(type.toString().toLowerCase(),
filterByType(ingredients, type));
}
model.addAttribute("design", new Taco());
return "design";
}
Controller process form method:
#PostMapping
public String processDesign(#Valid Taco taco, Errors errors)
{
if (errors.hasErrors())
{
return "design";
}
// Save the taco design...
// We will do this in chapter 3
log.info("Processing design: " + taco);
return "redirect:/orders/current";
}
I have no issue in displaying the form. All input fields are well received and processed. But whenever there is validation errors, and process form method call back to the form page "design", the form failed to parse with above mentioned errors.
I had tried:1. to disable validation on the Taco.name field;2. to remove the <span> which displays the name field errors. But none of them work.
Thanks in advance for your help.
I try change this code
#PostMapping
public String processDesign(#Valid Taco taco, Errors errors)
{
if (errors.hasErrors())
{
return "design";
}
// Save the taco design...
// We will do this in chapter 3
log.info("Processing design: " + taco);
return "redirect:/orders/current";
}
to
#PostMapping
public String processDesign(#Valid Taco taco, Errors errors)
{
if (errors.hasErrors())
{
return "redirect:/design";
}
// Save the taco design...
// We will do this in chapter 3
log.info("Processing design: " + taco);
return "redirect:/orders/current";
}
and it works.
I had a similar problem. This is what I did to fix it.
1st - change the opening header in design.html to the following
<form method="POST" th:object="${design}">
2nd - my processDesign() method looks like this:
public String processDesign(#Valid #ModelAttribute("design") Taco taco, Errors errors) {
if (errors.hasErrors()) {
return "design";
}
// this will save our Taco Design
// log.info("Processing design: " + design);
return "redirect:/orders/current";
}
I hope, that this helps and I'm not too late. In general, there are multiple similar errors in the book, that need to be fixed, but the community around it is great, so no need to worry.
Cheers
The code in book has some error, here is the right code from the github of book:
// tag::head[]
package tacos.web;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import lombok.extern.slf4j.Slf4j;
import tacos.Ingredient;
import tacos.Ingredient.Type;
import tacos.Taco;
#Slf4j
#Controller
#RequestMapping("/design")
public class DesignTacoController {
//end::head[]
#ModelAttribute
public void addIngredientsToModel(Model model) {
List<Ingredient> ingredients = Arrays.asList(
new Ingredient("FLTO", "Flour Tortilla", Type.WRAP),
new Ingredient("COTO", "Corn Tortilla", Type.WRAP),
new Ingredient("GRBF", "Ground Beef", Type.PROTEIN),
new Ingredient("CARN", "Carnitas", Type.PROTEIN),
new Ingredient("TMTO", "Diced Tomatoes", Type.VEGGIES),
new Ingredient("LETC", "Lettuce", Type.VEGGIES),
new Ingredient("CHED", "Cheddar", Type.CHEESE),
new Ingredient("JACK", "Monterrey Jack", Type.CHEESE),
new Ingredient("SLSA", "Salsa", Type.SAUCE),
new Ingredient("SRCR", "Sour Cream", Type.SAUCE)
);
Type[] types = Ingredient.Type.values();
for (Type type : types) {
model.addAttribute(type.toString().toLowerCase(),
filterByType(ingredients, type));
}
}
//tag::showDesignForm[]
#GetMapping
public String showDesignForm(Model model) {
model.addAttribute("design", new Taco());
return "design";
}
//end::showDesignForm[]
/*
//tag::processDesign[]
#PostMapping
public String processDesign(Design design) {
// Save the taco design...
// We'll do this in chapter 3
log.info("Processing design: " + design);
return "redirect:/orders/current";
}
//end::processDesign[]
*/
//tag::processDesignValidated[]
#PostMapping
public String processDesign(#Valid #ModelAttribute("design") Taco design, Errors errors, Model model) {
if (errors.hasErrors()) {
return "design";
}
// Save the taco design...
// We'll do this in chapter 3
log.info("Processing design: " + design);
return "redirect:/orders/current";
}
//end::processDesignValidated[]
//tag::filterByType[]
private List<Ingredient> filterByType(
List<Ingredient> ingredients, Type type) {
return ingredients
.stream()
.filter(x -> x.getType().equals(type))
.collect(Collectors.toList());
}
//end::filterByType[]
// tag::foot[]
}
// end::foot[]
and you can get all the source code from https://github.com/habuma/spring-in-action-5-samples
ps: In my opinion, the possible reason is that #valide Taco will transport a Taco object named taco to the template, while we use the design in the tempalte, so, the template cannot find the design which result in the error. And #ModelAttribute('design') can renamed the Taco object to design. On the other hand, we need the ingredients list to init the template whenever we visit the tacoDesign html, that is the reason that we separate the addIngredientsToModel method and using #ModelAttribute above it.

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NumberFormatException: null

Im trying to do full text search with spring data mongodb with all attributes of my model.
this the model:
#Document
public class Offre {
#Id
private String id;
#TextIndexed
private String titreOffre;
#TextIndexed
private String descriptionOffre;
#TextIndexed
private String date;
#TextIndexed
private String lieu;
}
the repository
public interface OffreRepository extends MongoRepository<Offre, String>, OffreRepositoryCustom,PagingAndSortingRepository<Offre, String> {
Offre findById(String id);
List<Offre> findAll();
}
public interface OffreRepositoryCustom {
public List<Offre> findFullTextSearch(String term);
}
public class OffreRepositoryImpl implements OffreRepositoryCustom{
#Override
public List<Offre> findFullTextSearch(String term){
Query query2 = new Query();
query2.addCriteria(Criteria.where("titreOffre").regex(term));
return mongoTemplate.find(query2, Offre.class);
}
}
this the service:
public class OffreService {
#Autowired
private OffreRepository offreRepository;
private OffreMapper mapper = new OffreMapper();
#Autowired
MongoTemplate template;
private Logger logger = Logger.getLogger(UserService.class);
public List<OffreUi> findFullTextSearch(String term) {
return mapper.toUIBean(offreRepository.findFullTextSearch(term));
}
}
this the controller
#Controller
#RequestMapping("/offres")
public class OffreController {
#Autowired
private OffreService service;
private Logger logger = Logger.getLogger(OffreController.class);
private DataTableResponseMap<OffreUi> offreResponseMap = new DataTableResponseMap<OffreUi>();
#RequestMapping (value = "/fulltext/{searchTerm}", method = RequestMethod.GET)
public String getfullPage(#RequestParam(value = "searchTerm", required = false) String searchTerm,Model model) {
model.addAttribute("offres", service.findFullTextSearch(searchTerm));
return "offre/fulltext";
}
#RequestMapping(value = "/fulltext")
public #ResponseBody
Map<String, ? extends Object> fulltext(
#RequestParam(required = false) String iDisplayStart,
#RequestParam(required = false) String iDisplayLength,
#RequestParam(value = "searchTerm", required = false) String searchTerm,
#RequestParam(required = false) String iSortingCols) {
int pageLength = Integer.parseInt(iDisplayLength);
int startPage = Integer.parseInt(iDisplayStart) / pageLength;
Pageable pageable = new PageRequest(startPage, pageLength);
Page<OffreUi> offres = (Page<OffreUi>) service.findFullTextSearch(searchTerm);
return offreResponseMap.mapOK(offres.getContent(),offres.getTotalElements());
}
}
this my view :
search.jsp:
<html lang="en">
<jsp:include page="../menu/header.jsp" />
<body>
<jsp:include page="../menu/topMenu.jsp" />
<div>
<form method="get"action="<c:url value='/offres/fulltext?searchTerm=${searchTerm}'/>">
<input type="text" name="searchTerm" id="searchTerm" value="searchTerm"/>
<input class="btn btn-primary" type="submit" value="Save">
</form>
</div>
</body>
</html>
and fulltextsearch.jsp
<html lang="en">
<jsp:include page="../menu/header.jsp" />
<body>
<jsp:include page="../menu/topMenu.jsp" />
<div class="container-fluid">
<div class="row-fluid">
<div class="span10">
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="example" >
<thead>
<tr>
<th width="20%">Titre Offre</th>
<th width="25%">Description Offre</th>
<th width="15%">Date</th>
<th width="15%">Site Entreprise</th>
<th width="15%">Logo Entreprise</th>
<th width="15%">Lieu</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="5" class="dataTables_empty">Loading data from server</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Titre Offre</th>
<th>Description Offre</th>
th>Date</th>
<th>Site Entreprise</th>
<th>Site Entreprise</th>
<th>Lieu</th>
</tr>
</tfoot>
</table>
</div><!--/span-->
<jsp:include page="../menu/rightMenu.jsp" />
</div><!--/row-->
<hr>
<footer>
<p>© Faycel Gsouma</p>
</footer>
</div><!--/.fluid-container-->
<jsp:include page="../menu/includeScripts.jsp" />
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
$('#example').dataTable( {
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": "<c:url value="/offres/fulltext?searchTerm=${searchTerm}"/>",
"fnServerData": function ( sSource, aoData, fnCallback ) {
$.ajax( {
"dataType": 'json',
"type": "GET",
"url": sSource,
"data": aoData,
"success": fnCallback
} );
},
"aoColumns": [
{ "mData": "titreOffre" },
{ "mData": "descriptionOffre" },
{ "mData": "date" },
{ "mData": "siteEntreprise" },
{ "mData": "logoEntreprise" },
{ "mData": "lieu" },
]
} );
} );
</script>
</body>
</html>
and this error that i get
exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NumberFormatException: null
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:943)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:822)
javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807)
javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
cause mère
java.lang.NumberFormatException: null
java.lang.Integer.parseInt(Integer.java:454)
java.lang.Integer.parseInt(Integer.java:527)
org.sab.sampleqa.web.controller.user.OffreController.fulltext(OffreController.java:185)
org.sab.sampleqa.web.controller.user.OffreController$$FastClassByCGLIB$$46319c43.invoke(<generated>)
org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:713)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.aop.interceptor.CustomizableTraceInterceptor.invokeUnderTrace(CustomizableTraceInterceptor.java:257)
org.springframework.aop.interceptor.AbstractTraceInterceptor.invoke(AbstractTraceInterceptor.java:112)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:646)
org.sab.sampleqa.web.controller.user.OffreController$$EnhancerByCGLIB$$e7945c7b.fulltext(<generated>)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:601)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:214)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:748)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:931)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:822)
javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807)
javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
note La trace complète de la cause mère de cette erreur est disponible dans les fichiers journaux de Apache Tomcat/8.0.18.
Your parameters are optional strings:
#RequestParam(required = false) String iDisplayStart,
#RequestParam(required = false) String iDisplayLength,
which you then parse:
int pageLength = Integer.parseInt(iDisplayLength);
which causes the NPE.
You should either check for null first:
int pageLength = null == iDisplayLength
? 10
: Integer.parseInt(iDisplayLength);
or use a defaultValue parameter to #RequestParam, e.g.
#RequestParam(required = false, defaultValue="0") String iDisplayStart,
#RequestParam(required = false, defaultValue="10") String iDisplayLength,

org.hibernate.QueryParameterException

I am newbie in spring. I'm trying to perform add,delete,edit operation on database through spring and hibernate.delete and add operation are successfully executed but When i am trying to edit by clicking on edit. i'm getting this error:
full stacktrace:
org.hibernate.QueryParameterException: could not locate named parameter [UserId]
at org.hibernate.engine.query.ParameterMetadata.getNamedParameterDescriptor(ParameterMetadata.java:75)
at org.hibernate.engine.query.ParameterMetadata.getNamedParameterExpectedType(ParameterMetadata.java:81)
at org.hibernate.impl.AbstractQueryImpl.determineType(AbstractQueryImpl.java:413)
at org.hibernate.impl.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:383)
at UserDao.userDaoImpl.getUserById(userDaoImpl.java:48)
at UserService.userServiceImpl.getUserById(userServiceImpl.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:108)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy17.getUserById(Unknown Source)
at UserController.userController.edit(userController.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:710)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:167)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
My jsp: "user.jsp"
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="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>Spring</title>
</head>
<body>
<h2>Add User Data</h2>
<form:form method="POST" modelAttribute="user" action="/SpringHibernate1/addUser">
<table>
<tr>
<td><form:label path="name">Name:</form:label></td>
<td><form:input path="name" value="${user.name}"/></td>
</tr>
<tr>
<td><form:label path="department">Department:</form:label></td>
<td><form:input path="department" value="${user.department}"/></td>
</tr>
<tr>
<td><form:label path="password">Password:</form:label></td>
<td><form:input path="password" value="${user.password}"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Submit"/></td>
</tr>
</table>
</form:form>
<h2>List users</h2>
<table align="left" border="1">
<tr>
<th>ID</th>
<th>Name</th>
<th>Department</th>
<th>Password</th>
<th>Actions on Row</th>
</tr>
<c:forEach items="${userList}" var="user1">
<tr>
<td><c:out value="${user1.id}"/></td>
<td><c:out value="${user1.name}"/></td>
<td><c:out value="${user1.department}"/></td>
<td><c:out value="${user1.password}"/></td>
<td align="center">Edit | Delete</td>
</tr>
</c:forEach>
</table>
</body>
</html>
Controller Class:" userController.java"
#Controller
public class userController {
#Autowired
private userService userService;
#RequestMapping("/user")
public String listUser(Map<String, Object> map) {
map.put("user", new User());
map.put("userList", userService.listUser());
return "user";
}
#RequestMapping(value = "/addUser",method = RequestMethod.POST)
public String addUser(#ModelAttribute("user")User user, BindingResult result)
{
if(null == user.getId()) {
userService.addUser(user);
}
else {
userService.updateUser(user);
}
return "redirect:/user";
}
#RequestMapping("/delete/{userId}")
public String deleteUser(#PathVariable("userId") Integer userId)
{
userService.deleteUser(userId);
return "redirect:/user";
}
#RequestMapping("/edit/{userId}")
public String edit(#PathVariable("userId")Integer userId,Map<String, Object> map)
{
map.put("user", userService.getUserById(userId));
map.put("userList", userService.listUser());
return "user";
}
}
Dao Implemetation: "userDaoImpl.java"
#Repository
public class userDaoImpl implements userDao {
#Autowired
private SessionFactory sessionFactory;
#Override
public void addUser(User user) {
sessionFactory.getCurrentSession().save(user);
}
#Override
public void deleteUser(Integer id) {
User user = (User)sessionFactory.getCurrentSession().load(User.class,id);
if(null != user) {
sessionFactory.getCurrentSession().delete(user);
}
}
#Override
#SuppressWarnings("unchecked")
public List<User> listUser() {
return sessionFactory.getCurrentSession().createQuery("from User").list();
}
#Override
public void updateUser(User user) {
sessionFactory.getCurrentSession().update(user);
}
#Override
#SuppressWarnings("unchecked")
public User getUserById(Integer id) {
Session session = sessionFactory.getCurrentSession();
List<User> list = session.createQuery("from User u where u.id = :id").setParameter("UserId",id).list();
return list.size() > 0 ?(User)list.get(0): null;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
need to change as below
List<User> list = session.createQuery("from User u where u.id = :id").setParameter("id",id).list();

Resources