Thymeleaf 和 Spring MVC 的表单参数为空

Posted

技术标签:

【中文标题】Thymeleaf 和 Spring MVC 的表单参数为空【英文标题】:Form parameter is null with Thymeleaf and Spring MVC 【发布时间】:2015-07-05 07:39:58 【问题描述】:

我遇到了 Thymeleaf 和 Spring MVC 的问题。

我正在学习 spring.io 网站 http://spring.io/guides/gs/handling-form-submission/ 的教程,当我尝试扩展此教程时,遇到了问题。

如果我在我的模型类中添加另一个参数(在我的示例中,我添加了一个 Date 参数和一个 long 参数),而不是将它们放在我的视图中(想象这个 date 参数是我的最后修改日期和这个长参数是一个随机值),当我提交这个值时,它使这两个参数在我的方法上为空。

这是我的一些代码。

我的模型类

public class Greeting 

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

我的控制器

@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";


我的表格

<!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>

结果页面

<!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>

这是我的模型类的控制台打印

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]

如您所见,我认为不在我视图中的两个参数在发布后(第二行)和第一行都变为 null,它们都有值。我不明白为什么,因为我来自另一个好的框架(JSF),我在那里没有这样的问题。只是要知道,我正在使用 spring 4,就像在教程中一样,为什么我有一个不在我看来的参数?因为其中一些参数会保存一些数据,例如上次注册更新日期、上次更新注册的用户和我的应用程序 ID。

谁能帮我找到答案?

编辑:

经过一段时间的实验,我找到了解决问题的方法。按照我的代码按原样工作:

@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】:

这是预期的行为。在问候view 时,您在response 中有model,但只要完成了http request/response,它就不再存在了。您将在&lt;form&gt; 标记中保存这些值,并且您需要在form submit 上提供这些值。

意思是,如果你想发回这些值,你需要添加 2 个隐藏的inputs 来保存这两个值。

<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>

【讨论】:

这是唯一的办法吗?我的意思是,如果我有一个包含十几个参数的模型,并且只需要编辑一个,我真的需要将它们全部作为隐藏字段吗?我可以制作一个“持久”的对象,直到我离开控制器吗? 既然你提到它,我们应该......但我相信百里香中没有这样的东西。您可能可以在春季将模型的范围设置为会话,但这不值得,因为您必须获取值并比较它们......而且,用户可能可以在不同的选项卡中打开相同的表单.

以上是关于Thymeleaf 和 Spring MVC 的表单参数为空的主要内容,如果未能解决你的问题,请参考以下文章

Thymeleaf 和 Spring MVC 的表单参数为空

Spring MVC 和 Thymeleaf 资源版本控制

Thymeleaf (Java Spring):无法让 mvc.uri 工作

Spring MVC 和 Thymeleaf 自定义错误消息类型转换

Thymeleaf 和 Spring MVC 电流控制器和动作

Spring MVC、Tiles2、ThymeLeaf 和自然模板