【问题标题】:How to work with the object in Thymeleaf dropdown如何使用 Thymeleaf 下拉列表中的对象
【发布时间】:2018-07-29 09:00:37
【问题描述】:

我是 Thymeleaf 的新手,遇到了一个奇怪的问题。让我先告诉你什么是有效的。我有两个简单的类

public class Country {

    private long countryid;

    private String name;
}

public class Person {

    private String name;

    private long countryId;
}

在 addPerson 页面中,我想从下拉列表中选择国家。我手动创建了一个国家列表(来自 spring 控制器),然后我的 addPerson.html 设计为

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <h1>Add Person</h1>
    <form action="#" th:action="@{/addPerson}" th:object="${person}"
        method="POST">
        <p>
            Name: <input type="text" th:field="*{name}" />
        </p>
        <select th:field="*{countryId}" class="form-control">
            <option th:each="country: ${countryList}"
                th:value="${country.countryid}" th:text="${country.name}"></option>
        </select>
        <p>
            <input type="submit" value="Submit" /> <input type="reset"
                value="Reset" />
        </p>
    </form>
</body>
</html>

当我从下拉列表中选择一个国家时,我得到了 countryid,一切正常。 现在我想改变我的 Person 类如下

public class Person {

    private String name;

    private Country country;
}

所以,我想要的是 country 对象本身,而不是 countryid。保持其他一切不变,我已将 addPerson.html 更改为

<select th:field="*{country}" class="form-control">
            <option th:each="country: ${countryList}"
                th:value="${country}" th:text="${country.name}"></option>
</select>

现在我可以看到下拉列表,但在提交时出现错误

出现意外错误(类型=错误请求,状态=400)。 object='person' 的验证失败。错误计数:1

简而言之:它适用于对象的属性,我需要做什么来处理整个对象本身?

请帮助。

更新 1:控制器方法签名

@GetMapping("/addPerson")
    public String addPerson(Model model) {

        Country country1 = new Country();
        country1.setCountryid(1);
        country1.setName("A");

        Country country2 = new Country();
        country2.setCountryid(2);
        country2.setName("B");

        List<Country> countryList = new ArrayList<Country>();
        countryList.add(country1);
        countryList.add(country1);

        model.addAttribute("countryList", countryList);
        model.addAttribute("person", new Person());
        return "addPerson";
    }

    @PostMapping("/addPerson")
    public void processAddPerson(@Valid @ModelAttribute("person") Person person) {

        System.out.println(person.getName());

    }

更新 2 经过调试,我发现第二种情况,在提交时,控件根本不会转到Person类的setCountry方法!

【问题讨论】:

  • 添加控制器方法签名。
  • @Alien:已更新。请检查。
  • 这只是一种解决方法,但在我的选择中,我们不需要在每个用例中都使用绑定。不要使用 th:field="*{country}" 属性。保持简单,1.) 使用 name="countryId",2.) 在 processAddPerson-method 中接收 countryId 作为额外参数,3.) 在方法中手动将 country-object “连接”到 person-object .绑定是创建的,但有时不值得不惜一切代价去做。
  • @Flocke:嗨,Flocke,非常感谢您的回复。我的实际用例有所不同,可以在这篇文章中找到 - stackoverflow.com/questions/51571933/… 。我缩小了当前帖子中的问题范围。如您所见,我确实需要选定的对象。为什么 setter 方法没有被调用真是令人惊讶!如果您有任何想法,请分享。
  • @user3274247:这不是百里香叶特有的麻烦。我从 spring-binding 和 jsp 中知道这一点,所谓的解决方案是定义自己的格式化程序(这就是你必须做的)。您生成的选项代码类似于 。那不是国家对象,而是字符串。因此,您需要一个 Formatter 来从该输入 ([1, UK]) 创建一个 Country-object 并在 Person-class 中进行注释。

标签: java spring-mvc spring-boot thymeleaf


【解决方案1】:

将 BindingResult 对象添加到您的方法中。

 public String processAddPerson( @Valid Person person,BindingResult bindingResult,Model model)

确保BindingResult 必须立即在使用@Valid 注释的对象之后。

【讨论】:

  • 您好外星人,感谢您的回答。但在控制器中,country 字段仍然为空。所以下拉选择不起作用。你能帮忙吗?
  • 尝试将 name="person" 放入 thymeleaf 选择标签并检查。
  • 没有成功 :( 我也用 name="country"/id="country" 试过了,没用!
  • 就像主线程中提到的:您需要定义一个 cosumer Formatter。
猜你喜欢
  • 2016-10-09
  • 2019-09-24
  • 1970-01-01
  • 1970-01-01
  • 2020-10-03
  • 2020-09-09
  • 1970-01-01
  • 2016-06-12
  • 1970-01-01
相关资源
最近更新 更多