Search code examples
javaspringspring-bootthymeleaf

Access Multiple beans using thymeleaf and springboot MVC


Trying to access multiple objects in the POST method using SpringBoot MVC and thymeleaf.

here is the controller.

@Controller
public class PatientController {    
    
    ObjectMapper Obj = new ObjectMapper();
    
          
    @GetMapping("/patient")
    public static String patientForm(Model model) {
        model.addAttribute("patient", new PatientDataModel());
        model.addAttribute("patient1", new PatientDataModel1());
        
        return "patient";
    }

    @RequestMapping(value="/patient", method=RequestMethod.POST, params="action=Send data to MongoDB cluster")
    public static String patientSubmit(@ModelAttribute("patient") PatientDataModel patient, @ModelAttribute("patient1") PatientDataModel patient1, Model model, Object obj ) throws JsonProcessingException {

model.addAttribute("patient", patient);
model.addAttribute("patient1", patient1);
    
return "result";
}

and here are the views:

patient.html

<form action="#" th:action="@{/patient}" th:object="${patient}" method="post">
    <div th:object="${patient1}" >
    <p>Patient Id: <input type="text" th:value="${patient.id}" /></p>
    <p>Patient Name: <input type="text" th:value="${patient.name}" /></p>
    <p>Message: <input type="text" th:value="${patient.content}" /></p>  
      <p>address: <input type="text" th:value="${patient1.address}" /></p>  
   </div>
            
    <p><input type="submit" name="action" value="Send data to MongoDB cluster" />
    <input type="reset" value="Reset" /></p>
</form>
</div>

and result.html

  <div class="starter-template">

    <h1>Result</h1>
    <p th:text="'id: ' + ${patient.id}" />
     <p th:text="'Name: ' + ${patient.name}" />
    <p th:text="'content: ' + ${patient.content}" />

      <p th:text="'address: ' + ${patient1.address}" />     
       
     
    <a href="/patient">Submit another message</a>
    </div>

and the bean classes are : PatientDataModel.java

  public class PatientDataModel {
    
    private long id;
    private String content;
    private String name;
    
    
    public PatientDataModel()
    {
        
    }
    
    
    
    public PatientDataModel(long id, String content, String name)
    {
        this.id = id;
        this.content = content;
        this.name = name;
    }
    

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
    
       @Override
       public String toString()
       {
          return "Patient [id=" + id + ", firstName=" + name + ", " +
                "content=" + content + "]";
       }

}

another bean :

public class PatientDataModel1 {
    
    private String address;
    
    @Override
    public String toString() {
        return "Patient1 [address=" + address + "]";
    }


    public PatientDataModel1()
    {
        
    }
    

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

}

now , the issue is , I need both the beans to be accessible in the GET and POST method. when I am running the code , it is executing but the beans does not have values , all are null . pls suggest


Solution

  • It will be easiest to have 1 object to find to the form. Create a new class PatientFormData for example that contains all the fields from the 2 objects and convert from/to the objects you have in the get and post methods in your controller.

    For example:

    public class PatientFormData {
        private long id;
        private String content;
        private String name;
        private String address;
    
        public static PatientFormData from(PatientDataModel model,
    PatientDataModel1 model1) {
            id = model.getId();
            content = model.getContent();
            name = model.getName();
            address = model.getAddress();
        }
    
        public PatientDataModel createPatientDataModel() {
            PatientDataModel result = new PatientDataModel();
            result.setId(id);
            result.setContent(content);
            result.setName(name);
            return result;
        }
    
        // getters and setters here
    }
    

    Use this in the controller:

    @Controller
    public class PatientController {    
        
        ObjectMapper Obj = new ObjectMapper();
        
              
        @GetMapping("/patient")
        public static String patientForm(Model model) {
            PatientFormData formData = PatientFormData.from(new PatientDataModel(), new PatientDataModel1());
    
            model.addAttribute("patientFormData", formData);
            
            return "patient";
        }
    
        @RequestMapping(value="/patient", method=RequestMethod.POST, params="action=Send data to MongoDB cluster")
        public static String patientSubmit(@ModelAttribute("patientFormData") PatientFormData formData, Model model, Object obj ) throws JsonProcessingException {
    
            PatientDataModel model = formData.createPatientDataModel();
            PatientDataModel1 model1 = formData.createPatientDataModel1();
    
            // Do more processing with objects
        
        return "result";
    }
    

    Also be sure to correctly use the field binding using *{..}:

    <form action="#" th:action="@{/patient}" th:object="${patientFormData}" method="post">
        <p>Patient Id: <input type="text" th:value="*{id}" /></p>
        <p>Patient Name: <input type="text" th:value="*{name}" /></p>
        <p>Message: <input type="text" th:value="*{content}" /></p>  
          <p>address: <input type="text" th:value="*{address}" /></p>  
       </div>
                
        <p><input type="submit" name="action" value="Send data to MongoDB cluster" />
        <input type="reset" value="Reset" /></p>
    </form>
    </div>