Form parameter is null with Thymeleaf and Spring M

2019-01-26 16:03发布

问题:

i'm having a problem with Thymeleaf and Spring MVC.

I'm following a tutorial from spring.io website http://spring.io/guides/gs/handling-form-submission/ and when I've tried to expand this tutorial, I ran into a problem.

If I add another parameter to my model class (on my example, I've added a Date parameter and a long parameter), and not put them on my view (just imagine that this date parameter is my last modification date and this long parameter is a random value), when I submit this value, it makes this 2 parameters null on my method.

Here are some of my code.

My model Class

public class Greeting {

    private long id;
    private String content;
    private Date hour;
    private long longNumber;
.... getters and setters ....
}

My Controller

@Controller
public class GreetingController {

@RequestMapping(value="/greeting", method=RequestMethod.GET)
public String greetingForm(Model model) {

    Greeting greeting = new Greeting();
    greeting.setHour(new Date());
    greeting.setLongNumber(1234L);
    System.out.println(greeting.toString());
    model.addAttribute("greeting", greeting);
    return "greeting";
}

@RequestMapping(value="/greeting", method=RequestMethod.POST)
public String greetingSubmit(@ModelAttribute Greeting greeting, Model model) {
    System.out.println(greeting.toString());
    model.addAttribute("greeting", greeting);
    return "result";
}
}

My Form

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Getting Started: Handing Form Submission</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <h1>Form</h1>
    <form action="#" th:action="@{/greeting}" th:object="${greeting}" method="post">
        <p>Id: <input type="text" th:field="*{id}" /></p>
        <p>Message: <input type="text" th:field="*{content}" /></p>
        <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
    </form>
</body>
</html>

The result page

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Getting Started: Handing Form Submission</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <h1>Result</h1>
    <p th:text="'id: ' + ${greeting.id}" />
    <p th:text="'content: ' + ${greeting.content}" />
    <p th:text="'Date: ' + ${greeting.hour}" />
    <a href="/greeting">Submit another message</a>
</body>
</html>

This are my console prints of my model class

Greeting [id=0, content=null, hour=Sun Apr 26 22:29:25 GMT-03:00 2015, longNumber=1234]
Greeting [id=0, content=aaaa, hour=null, longNumber=0]

As you can see, both of my parameters that are not in my view, become null after the post (the second line) and on the first line, they have values. I don't understand why, because I came from another good framework (JSF) and I don't have such a problem there. Just to know, I'm using spring 4, just like on the tutorial, and why I have a parameter that is not on my view? Because some of this parameters will hold some data just like last register updated date, last user who updated the register and my application ID.

Can anyone help me find an answer for this?

Edit:

After some time and experimentation, I found a solution to my problem. Follow my piece of code that works just as it meant to be:

@Controller
@SessionAttributes({"obj"})
public class MyController {

    @RequestMapping(value = "/path", method = RequestMethod.GET)
    public ModelAndView myGet() {       
        ModelAndView modelAndView = new ModelAndView("view");
        MyClass object = new MyClass();
        modelAndView.addObject("obj", object );     
        return modelAndView;
    }

    @RequestMapping(value = "/path", method = RequestMethod.POST)
    public ModelAndView myPost(@ModelAttribute("obj") @Validated MyClass object, BindingResult result){

        ModelAndView modelAndView = new ModelAndView("view");       
        if(result.hasErrors())
            modelAndView.addObject("obj",object);
        else 
            service.save(object);
        return modelAndView;
    }   
}

回答1:

This is the expected behavior. You have the model in the response while getting to your greetings view, but as long as that http request/response is done, it doesn't exist anymore. You will hold the values in the <form> tag and you will need to provide these values upon form submit.

Meaning, that if you want to send these values back you will need to add 2 hidden inputs to hold these two values.

<form action="#" th:action="@{/greeting}" th:object="${greeting}" method="post">
    <p>Id: <input type="text" th:field="*{id}" /></p>
    <p>Message: <input type="text" th:field="*{content}" /></p>
    <input type="hidden" th:field="*{hour}" />
    <input type="hidden" th:field="*{longNumber}" />
    <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>