Thymeleaf 和 SpringBoot 的下拉列表 [英] dropdown lists with Thymeleaf and SpringBoot

查看:135
本文介绍了Thymeleaf 和 SpringBoot 的下拉列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在 HTML 上使用 Thymeleaf 的 Spring Boot 1.3 应用程序.我有用户页面,当我编辑它们时,我希望从列表中选择用户机构.我的窗口显示一切正常,但是当我选择机构时,控制器没有显示选择的值.

这是我的 HTML:

 

<label class="col-md-3 control-label">机构</label><div class="col-md-5"><div th:if="${institutionList != null 而不是 #lists.isEmpty(institutionList)}"><选择><option th:each="dropDownItem : ${institutionList}"th:value="${dropDownItem.name}"th:text="${dropDownItem.name}"/></选择>

<div th:if="${institutionList == null or lists.isEmpty(institutionList)}"><div>未找到任何机构,请先创建一些"</div>

这是我的控制器

@Controller@PreAuthorize("hasRole('Admin')")@RequestMapping("/admin")公共类 AdminController {@交易@PreAuthorize("hasRole('ADMIN')")@RequestMapping(value = "/addUser", method = RequestMethod.POST)public String checkPersonInfo(@ModelAttribute User user, Model model, Authentication authentication) {//用户没有选择的机构集customUserDetailsS​​ervice.createNewUser(user);updateModelWithAllUsers(model);返回管理员";}私人无效updateModelWithAllUsers(模型模型){model.addAttribute(USERLIST, customUserDetailsS​​ervice.findAllUsers());模型.addAttribute(INSTITUTION_LIST,institutionService.findAll());model.addAttribute("user", new User());}...}

这是我的用户:

@Entity@Table(name = "用户")公共类用户实现 UserDetails {@Id私人字符串用户名;@Column(可为空 = 假)私人字符串密码;启用私有布尔值;私人布尔帐户NonExpired;私人布尔帐户非锁定;私人布尔凭据NonExpired;私人字符串公司名称;私人字符串电子邮件;@ElementCollection(fetch=FetchType.EAGER)@CollectionTable(name="Authorities", joinColumns=@JoinColumn(name="username"))@Column(name="权限")私有集角色 = 新 HashSet();@ManyToOne(fetch = FetchType.EAGER, 级联 = CascadeType.ALL)@JoinColumn(name = "institutionId", nullable = false)私立机构;...吸气剂和二传手}

还有我的机构:

@Entity@Table(name = "机构")公共类机构{@Id@GeneratedValue(策略 = GenerationType.IDENTITY)私人长机构ID;私人字符串名称;@OneToMany(mappedBy = "institution", fetch = FetchType.EAGER)@Fetch(value = FetchMode.SUBSELECT)列出<用户>用户 = 新的 ArrayList<用户>();...吸气剂和二传手}

当/addUser"从用户界面获取用户对象时,机构为空.

编辑我使用 Sergios 建议使用 select th:field="${user.institution}" 以及 select th:field="*{institution}"

>

但这给了我一个错误:

<块引用>

org.springframework.validation.BeanPropertyBindingResult: 1 个错误字段机构"上的对象用户"中的字段错误:拒绝值[com.security.Institution@3e3945d2];代码[typeMismatch.user.institution,typeMismatch.institution,typeMismatch.com..security.Institution,typeMismatch];争论[org.springframework.context.support.DefaultMessageSourceResolvable:代码 [user.institution,institution];参数 [];默认消息[机构]];默认消息 [无法转换属性值将 'java.lang.String' 输入到所需的类型 'com.security.Institution'对于财产机构";嵌套异常是org.springframework.core.convert.ConversionFailedException:未能从类型 java.lang.String 转换为类型 java.lang.Long 作为值'com.security.Institution@3e3945d2';嵌套异常是java.lang.NumberFormatException:对于输入字符串:com..security.Institution@3e3945d2"]

不确定我是否正确阅读,但这是否意味着 Thymeleaf 正在尝试将 Institution.name 传递给 user.institution 字段?

谁能就如何做到这一点提供任何建议?

解决方案

您忘记指明必须从其中获取所选值的字段:

示例:我假设 User 类具有机构属性.

<label class="col-md-3 control-label">机构</label><div class="col-md-5"><div th:if="${institutionList != null 而不是 #lists.isEmpty(institutionList)}"><select th:field="*{机构}"><option th:each="dropDownItem : ${institutionList}"th:value="${dropDownItem.name}"th:text="${dropDownItem.name}"/></选择>

<div th:if="${institutionList == null or lists.isEmpty(institutionList)}"><div>未找到任何机构,请先创建一些"</div>

更多信息:http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#dropdownlist-selectors

您需要向您的应用程序指明如何将表单(字符串类型)内返回的机构 ID 转换为机构实体.为此,您必须使用转换器.

首先将option的值改成institutionId:

<label class="col-md-3 control-label">机构</label><div class="col-md-5"><div th:if="${institutionList != null 而不是 #lists.isEmpty(institutionList)}"><select th:field="*{机构}"><option th:each="dropDownItem : ${institutionList}"th:value="${dropDownItem.institutionId}"th:text="${dropDownItem.name}"/></选择>

<div th:if="${institutionList == null or lists.isEmpty(institutionList)}"><div>未找到任何机构,请先创建一些"</div>

您必须创建一个实现 Converter 接口的类.

@Component公共类 StringToInstitution 实现了 Converter{@自动连线私人机构知识库;//或实现存储库的类.@覆盖公共机构转换(字符串 arg0){Long id = new Long(arg0);返回 repository.findOne(id);}}

I have a Spring Boot 1.3 app that uses Thymeleaf on the HTML. I have page of users and when I edit them, I would like the user institution selected from a list. I have the window showing everything properly, but when I select the institution, the controller does not show the selected value.

Here is my HTML:

 <div class="form-group">
     <label class="col-md-3 control-label">Institution</label>
         <div class="col-md-5">
         <div th:if="${institutionList != null and not #lists.isEmpty(institutionList)}">
             <select>
                 <option th:each="dropDownItem : ${institutionList}"
                                 th:value="${dropDownItem.name}"
                                 th:text="${dropDownItem.name}" />
             </select>
        </div>
        <div th:if="${institutionList == null or lists.isEmpty(institutionList)}">
            <div>"No Institutions were found, please create some first"</div>
        </div>
    </div>
 </div>

And here is my controller

@Controller
@PreAuthorize("hasRole('Admin')")
@RequestMapping("/admin")
public class AdminController {
    @Transactional
    @PreAuthorize("hasRole('ADMIN')")
    @RequestMapping(value = "/addUser", method = RequestMethod.POST)
    public String checkPersonInfo(@ModelAttribute User user, Model model, Authentication authentication) {
        // user does not have the selected institution set
        customUserDetailsService.createNewUser(user);
        updateModelWithAllUsers(model);
        return "admin";
    }

    private void updateModelWithAllUsers(Model model) {
        model.addAttribute(USERLIST, customUserDetailsService.findAllUsers());
        model.addAttribute(INSTITUTION_LIST, institutionService.findAll());
        model.addAttribute("user", new User());
    }

...
}

Here is my User:

@Entity
@Table(name = "Users")
public class User implements UserDetails {
 @Id
    private String username;

    @Column(nullable = false)
    private String password;

    private boolean enabled;
    private boolean accountNonExpired;
    private boolean accountNonLocked;
    private boolean credentialsNonExpired;
    private String companyName;
    private String email;

    @ElementCollection(fetch=FetchType.EAGER)
    @CollectionTable(name="Authorities", joinColumns=@JoinColumn(name="username"))
    @Column(name="authority")
    private Set<String> roles = new HashSet<String>();

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "institutionId", nullable = false)
    private Institution institution;
... getters & setters
}

And my Institution:

@Entity
@Table(name = "Institution")
public class Institution {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long institutionId;
    private String name;

    @OneToMany(mappedBy = "institution", fetch = FetchType.EAGER)
    @Fetch(value = FetchMode.SUBSELECT)
    List<User> users = new ArrayList<User>();
    ... getters & setters
}

When the "/addUser" gets the User object from the UI, the institution is null.

EDIT I used Sergios suggestion to use select th:field="${user.institution}" as well as select th:field="*{institution}"

but that gives me an error:

org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'user' on field 'institution': rejected value [com.security.Institution@3e3945d2]; codes [typeMismatch.user.institution,typeMismatch.institution,typeMismatch.com. .security.Institution,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.institution,institution]; arguments []; default message [institution]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'com.security.Institution' for property 'institution'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type java.lang.Long for value 'com.security.Institution@3e3945d2'; nested exception is java.lang.NumberFormatException: For input string: "com. .security.Institution@3e3945d2"]

Not sure if I am reading this correctly, but does that mean Thymeleaf is trying to pass the Institution.name to the user.institution field?

Can anyone offer any advice on how to do this?

解决方案

You have forgot indicate the field from where it has to take the selected value:

Example: I supousse the User class has an attribute for institution.

<div class="form-group">
 <label class="col-md-3 control-label">Institution</label>
     <div class="col-md-5">
     <div th:if="${institutionList != null and not #lists.isEmpty(institutionList)}">
         <select th:field="*{institution}">
             <option th:each="dropDownItem : ${institutionList}"
                             th:value="${dropDownItem.name}"
                             th:text="${dropDownItem.name}" />
         </select>
    </div>
    <div th:if="${institutionList == null or lists.isEmpty(institutionList)}">
        <div>"No Institutions were found, please create some first"</div>
    </div>
</div>

More info: http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#dropdownlist-selectors

EDIT: You need to indicate to your app how convert a Id of Insitution returned inside form (String type) to a Institution entity. For that you have to use a Converter.

First change the value of option to institutionId:

<div class="form-group">
 <label class="col-md-3 control-label">Institution</label>
     <div class="col-md-5">
     <div th:if="${institutionList != null and not #lists.isEmpty(institutionList)}">
         <select th:field="*{institution}">
             <option th:each="dropDownItem : ${institutionList}"
                             th:value="${dropDownItem.institutionId}"
                             th:text="${dropDownItem.name}" />
         </select>
    </div>
    <div th:if="${institutionList == null or lists.isEmpty(institutionList)}">
        <div>"No Institutions were found, please create some first"</div>
    </div>
</div>

You have to create a class that implements the Converter interface.

@Component
public class StringToInstitution implements Converter<String, Institution> {

@Autowired
private InstitutionRepository repository; //Or the class that implments the repository.

    @Override
    public Institution convert(String arg0) {
        Long id = new Long(arg0);
        return repository.findOne(id);
    }

}

这篇关于Thymeleaf 和 SpringBoot 的下拉列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆