【问题标题】:Thymeleaf select getting selected objectThymeleaf 选择获取选定对象
【发布时间】:2017-08-26 15:04:40
【问题描述】:

我有一个 Thymeleaf 表格。带有一个选择字段。

<form th:object="${contactForm}" th:action="@{/contact}" method="post">
<select th:field="*{cityId}">
        <option th:each="item : ${cityList}"
                th:value="${item.id}" th:text="${item.description}">
</select> 

当我提交表单时,我可以在城市字段中获取城市 ID。是否可以将城市 ID 和描述作为对象。如果我的联系人表单中有一个城市对象。

【问题讨论】:

    标签: spring-mvc thymeleaf


    【解决方案1】:

    当前代码

    我只是假设您正在使用基于您的 html 的以下类,所以让我们以它们为起点。

    /* This may be called City in your code */
    public class Item {
        private Long id;
        private String description;
    
        // getter/setter/constructor here...
    }
    
    public class ContactForm {
        private Long cityId;
    
        // getter/setter/constructor here...
    }
    

    现在我们可以做些什么来解决您的问题?

    Spring 提供了一种为特定类添加转换器的简单方法,因此您不必担心将 String 转换为 Year 对象。同样的技术也可以用于其他类,比如你的 Item 类!让我们研究一下:

    import org.springframework.core.convert.converter.Converter;
    import org.springframework.stereotype.Component;
    
    @Component
    public class StringToItemConverter implements Converter<String, Item> {
        @Override
        public Item convert(String source) {
            if(source != null) {
                try {
                    Long id = Long.parseLong(source);
                    return /* insert your logic for getting an item by it's id here */;
                } catch(Exception e) {
                    return null;
                }
            }
            return null;
        }
    }
    

    当 Spring 尝试将 String(来自您的表单输入)转换为类型为 Item 的实际 java 字段时,Spring 会自动执行上述代码。所以如果我们稍微改变一下你的 ContactForm 类,spring 会自动为给定的 id 分配 Item 对象。

    public class ContactForm {
        /* Note that cityId now has all the information you need (id and description) You should however consider renaming it to city. Don't forget to change the th:field name too! ;) */
        private Item cityId;
    
        // getter/setter/constructor here...
    }
    

    您正在使用 Spring 存储库吗?

    如果您将项目存储在数据库中,您很可能会为此使用 CrudRepository。在这种情况下,代码可能如下所示。假设您的 Repository 类名为 ItemRepository。

    @Component
    public class StringToItemConverter implements Converter<String, Item> {
        private ItemRepository itemRepository;
    
        @Autowired
        public void setItemRepository (ItemRepository itemRepository) {
            this.itemRepository = itemRepository;
        }
    
        @Override
        public Item convert(String source) {
            if(source != null) {
                try {
                    Long id = Long.parseLong(source);
                    return itemRepository.findOne(id);
                } catch(Exception e) {
                    return null;
                }
            }
            return null;
        }
    }
    

    上面的代码会尝试通过在数据库中查找 id 来将表单中的字符串转换为实际的Item-Object。所以我们要么得到Item,要么得到null,如果出现任何问题(例如,如果没有该id的项目或者字符串不能被解析那么长)。

    【讨论】:

    • 感谢您的详细解答。所以为了获得项目对象我必须点击数据库?我希望像 th:value="${item}" 这样的东西,当发布 Item 对象时,它是由它构造的,而不会命中 DB。我想要一些类似 Angular JS ng-model="item" 的东西,当我发布 ContactForm 时,spring 会自动从 @RequestBody 构造 ConcatForm 和 Item 对象。但我知道这是我们使用服务器端模板时的限制
    • 您不必从数据库中查找它。您通常如何通过代码中的 id 查找项目?
    • 我会使用 itemRepository.findOne(id);如果对象不在缓存中,那么它会命中数据库吗?
    猜你喜欢
    • 2020-12-20
    • 2018-04-11
    • 1970-01-01
    • 2019-05-18
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 2020-01-13
    相关资源
    最近更新 更多