'This application has no explicit mapping for /error bad request 400

I have a small spring boot project,, which works fine . But, I tried to add some kind of validation.. I worked on one html page but failed on the other with no feasible reason !

Here is the html page (addProcedure.html):

    <!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Add Procedure Form</title>




</head>


<body>
    <div class="container">
        <br />
        <h3>Add New Procedure </h3>
        <br />
        <hr />
        <br />
        <form th:action="@{/surgerywaitinglist/saveToWaitinList}" th:object="${waitinglist}"
            method="POST">

            <table class="table table-primary table-bordered table-striped"
                id="employeeTable" style="width: 50%" align="center">
                <thead>

                </thead>

                <tbody>
                    <tr>
                        <td>MRN</td>
                        <td th:text="${patient.patientId}"></td>
                    </tr>
                    <tr>
                        <td>Name</td>
                        <td
                            th:text="${patient.patientFirstName} +' '+ ${patient.patientLastName}"></td>
                    </tr>
                    <tr>
                        <td>Gender</td>
                        <td th:text="${patient.patientGender}"></td>
                    </tr>
                    <tr>
                        <td>Contact</td>
                        <td th:text="${patient.patientConact}"></td>
                    </tr>
                    <tr>
                        <td>Procedure</td>
                        <td><input type="text"
                            th:field="${waitinglist.waitingListProcedure}"
                            class="form-control col-4 mb-4" placeholder="Enter Procedure" id="waitingListProcedure"></input>
                            
                            <!-- <div class="alert alert-warning"
                                th:if="${#fields.hasErrors('waitingListProcedure')}"
                                th:errors="*{waitingListProcedure}"></div> -->
                                
                            <div class="alert alert-warning"
                                th:if="${#fields.hasErrors('waitingListProcedure')}"
                                th:errors="*{waitingListProcedure}"></div>
                                </td>
                    </tr>
                    <tr>
                        <td>Diagnosis</td>
                        <td><input type="text"
                            th:field="${waitinglist.waitingListDiagnosis}"
                            class="form-control col-4 mb-4" placeholder="Enter Diagnosis" />
                        </td>
                    </tr>
                    <tr>
                        <td>Department</td>
                        <td>
                            <div class="form-group">

                                <!--/////////// working fine,,, bur I need to fetch data from inside the ajax code   -->
                                <!-- working fine but returned departmentName as departmentId  -->
                                <!-- <select th:field="${waitinglist.waitingListDepartmentId}" class="form-control" id="department">

                                    <option th:each="department: ${departments}"
                                        th:value="${department.departmentName}"
                                        th:text="${department.departmentName}"></option>

                                </select> -->


                                <select name="departmentName"
                                    th:with="departmentName = ${department.departmentName}"
                                    class="form-control" id="department">

                                    <option value="" th:selected="selected" th:disabled="disabled">select
                                        option</option>
                                    <option th:each="department: ${departments}"
                                        th:value="${department.departmentName}"
                                        th:text="${department.departmentName}"></option>

                                </select>



                            </div>
                        </td>



                    </tr>
                    <tr>
                        <td>Surgeon</td>
                        <td>
                            <div class="form-group">

                                <!-- working fine but returned surgeonName as departmentId  -->
                                <!-- <select th:field="${waitinglist.waitingListSurgeonId}" class="form-control" id="surgeonId">
                                </select> -->


                                <select th:field="${surgeon.surgeonLastName}"
                                    class="form-control" id="surgeonId">
                                </select>

                            </div>



                        </td>


                    </tr>

                    <tr>
                        <td>Addition Date</td>
                        <td><input type="date"
                            th:field="${waitinglist.waitingListAdditionDate}"
                            class="form-control col-4 mb-4" placeholder="Pick Date" /></td>
                    </tr>
                    <tr>
                        <td>Acttual Booking Date</td>
                        <td><input type="date"
                            th:field="${waitinglist.waitingListActualBookingDate}"
                            class="form-control col-4 mb-4" placeholder="Pick Date" /></td>
                    </tr>


                </tbody>


            </table>
            <br />
            <hr />
            <br /> <input type="hidden" th:field="${patient.patientId}" />

            <div style="text-align: center;">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>

        </form>
        <br /> <br />
        <div style="text-align: center;">
            <a th:href="@{/surgerywaitinglist}">Back To List</a>
        </div>

    </div>



</body>
</html>

For the Controller:

@PostMapping(value="/surgerywaitinglist/saveToWaitinList")
    public String saveToWaitinList(@Valid WaitingList waitinglist, Surgeon surgeon,   Department department , BindingResult result, Model model, @PathVariable Long patientId) {
        System.out.println("in /surgerywaitinglist/saveToWaitinList");
        System.out.println("result: "+ result);
        
        boolean thereAreErrors = result.hasErrors();
        
        if(thereAreErrors) {
        //if(result.hasErrors()) {
            
            return "addProcedure";
            }
        
        if(waitinglist.getWaitingListId()==null) {
            System.out.println("saveToWaitinglist waitinglist: " + waitinglist);
            Department tempDepartment = depRepo.findByDepartmentName(department.getDepartmentName());
            Surgeon temSurgeon = surgeonRepo.findBySurgeonLastName(surgeon.getSurgeonLastName());
            System.out.println("saveToWaitinglist tempSurgeon: " + temSurgeon);
            System.out.println("saveToWaitinglist tempDepartment: " + tempDepartment);
            
            waitinglist.setWaitingListSurgeonId(temSurgeon.getSurgeonId());
            waitinglist.setWaitingListDepartmentId(tempDepartment.getDepartmentId());
            waitinglist.setWaitingListPatientId(patientId);
            
            waitingListRepo.save(waitinglist);
        }
        
        else {
            System.out.println("saveToWaitinglist waitinglist else: " + waitinglist);
            Department tempDepartment = depRepo.findByDepartmentName(department.getDepartmentName());
            Surgeon temSurgeon = surgeonRepo.findBySurgeonLastName(surgeon.getSurgeonLastName());
            waitinglist.setWaitingListActualBookingDate(waitinglist.getWaitingListActualBookingDate());
            waitinglist.setWaitingListAdditionDate(waitinglist.getWaitingListAdditionDate());
            waitinglist.setWaitingListProcedure(waitinglist.getWaitingListProcedure());
            waitinglist.setWaitingListDiagnosis(waitinglist.getWaitingListDiagnosis());
            waitinglist.setWaitingListSurgeonId(temSurgeon.getSurgeonId());
            waitinglist.setWaitingListDepartmentId(tempDepartment.getDepartmentId());
            waitinglist.setWaitingListPatientId(patientId);
            waitingListRepo.save(waitinglist);
        }
        return "redirect:/surgerywaitinglist";
        
    }

The entity class with the validation annotations,,

package com.WaitingListThymeleaf.entity;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;

import lombok.Data;

@Data
@Entity
@Table(name="waitingList")
public class WaitingList {

    @Id
    @GeneratedValue
    private Long waitingListId;
    @NotEmpty(message = "Please enter a procedure")
    //@Size(min=5, max=30)
    private String waitingListProcedure;
    private String waitingListDiagnosis;
    private Long waitingListPatientId;
    private Long waitingListSurgeonId;
    private Long waitingListDepartmentId;
    @DateTimeFormat(iso=ISO.DATE)
    private Date waitingListAdditionDate;
    @DateTimeFormat(iso=ISO.DATE)
    private Date waitingListActualBookingDate;
}

I have tried @NotNull , @NotEmpty and @NotBlank with no luck... It seems the validation works. However, I don't get to the html page !

Instead, I get the following:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sat May 07 21:39:57 MSK 2022
There was an unexpected error (type=Bad Request, status=400).
Validation failed for object='waitingList'. Error count: 1
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'waitingList' on field 'waitingListProcedure': rejected value []; codes [NotEmpty.waitingList.waitingListProcedure,NotEmpty.waitingListProcedure,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [waitingList.waitingListProcedure,waitingListProcedure]; arguments []; default message [waitingListProcedure]]; default message [Please enter a procedure]
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:175)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:179)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:146)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:831)

enter image description here



Solution 1:[1]

I re-arranged the method parameters.... apparently, the BindingResult should always come immediately after the object that needs validating...

public String saveToWaitinList(@Valid WaitingList waitinglist, BindingResult result,
            Surgeon surgeon, Department department,
            Patient tempPatient, Model model) {

Thanx to @Scirocco's post here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 AdelLinux80s