How @ModelAttribute for method parameter work in Spring MVC

606 Views Asked by At

i'm very new in spring mvc so i have very confused about how @modelAttribute work in spring mvc and i have situation right down

my JSP:

 <%-- 
    Document   : login
    Created on : Apr 3, 2023, 11:22:57 AM
    Author     : MinhDuy
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"  %>

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>Hello World!</h1>
       

        <form:form action="login" method="POST" modelAttribute="user1" >
            User: <form:input path="username"/><br>
            Pass: <form:input path="password"/><br>
            <input type="submit" value="login">

        </form:form>
    </body>
</html>

and my Controller:

/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
 */
package com.mycompany.mavenproject3;

import com.mycompany.mavenproject3.Model.Account;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 *
 * @author MinhDuy
 */
@Controller
public class TestController {

   @RequestMapping("/hello")
    public String test(@ModelAttribute("zeus") Account account) {
        System.out.println(account);
        return "hello";
    }

    @RequestMapping(method = RequestMethod.GET, value = "/login")
    public String login(Model model) {
        Account u = new Account();
        u.setUsername("daniel");
        u.setPassword("123456");
        model.addAttribute("user1", u);
        return "login";
    }

     @RequestMapping(method = RequestMethod.POST, value = "/login")
    public String checkLog(@ModelAttribute("zeus") Account u) {
        System.out.println(u);
        return "hello";
    }


    
    @ModelAttribute
    public void addAccount(Model model) {
        Account a = new Account();
        a.setUsername("zeus");
        a.setPassword("123");
        model.addAttribute("zeus", a);
    }
   
}

i'm very confused that when submit form and the method checkLog is called, instead of retrieving attribute named "zeus" in Model , spring mvc seemed get the paramater value from submitform bind to User then over written model attribute named "zeus". Therefore i get OUTPUT like

User{username=user name i submited, password=submited}

insteed of

User{username=zeus, password=123}

i dont know how flow of @modelAttribute, when not submit form, I can get attribute named "zeus" from Model (called test() function) but when submit form it can't be done as above, please shed the light for me on this problems tks you guys very much

2

There are 2 best solutions below

1
Milind Vedi On BEST ANSWER

Yes, it will work that way only. If you want to checkLog with "zeus" you need to use


     @RequestMapping(method = RequestMethod.POST, value = "/login")
    public String checkLog(@ModelAttribute Account u) {
        Account a = model.getAttribute("zeus");
        if(a.getUsername().equals(u.getUserame() && a.getPassword().equals(u.getPassword()) {
         // do your stuff here
         }
        return "hello";
    }
//Understnad the flow: Just like
//if you write 
String s1 = "value1";
String s2 = "value2"
model.addAtribute("zeus", s1);
//and in the next line if you write
model.addAtribute("zeus", s2);
//the value of zeus will change from s1 to s2 
//similarly in your code the value of "zeus" gets changed when you write
// (@ModelAttribute("zeus") Account u)
2
Ashad0203 On

Point 1.

@ModelAttribute
public void addAccount(Model model) {
    Account a = new Account();
    a.setUsername("zeus");
    a.setPassword("123");
    model.addAttribute("zeus", a);
}

The above code is just to set default values when the value is not provided in the form.

Point 2.

Since the modelAttribute value used in the <form: form> tag is "user1", which does not match the attribute name used in the @ModelAttribute annotation in the controller method.

When the form is submitted, Spring MVC will create a new instance of the Account class and bind the form data to this new instance. The Account instance will have default values for all properties except for "username" and "password", which will be set to the values submitted in the form.

This is the same thing that is happening in your code