【问题标题】:dropdown lists with Thymeleaf and SpringBootThymeleaf 和 Spring Boot 的下拉列表
【发布时间】:2016-06-12 15:08:43
【问题描述】:

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

这是我的 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>

这是我的控制器

@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());
    }

...
}

这是我的用户:

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

还有我的机构:

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

“/addUser”从UI获取User对象时,机构为空。

编辑 我使用 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 正在尝试将机构名称传递给 user.institution 字段?

任何人都可以就如何做到这一点提供任何建议吗?

【问题讨论】:

    标签: spring-mvc spring-boot thymeleaf


    【解决方案1】:

    您忘记指明必须从哪个字段获取所选值:

    示例:我认为 User 类有一个机构属性。

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

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

    编辑: 您需要向您的应用指示如何将在表单(字符串类型)中返回的机构 ID 转换为机构实体。为此,您必须使用转换器。

    首先将option的值改为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>
    

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

    @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);
        }
    
    }
    

    【讨论】:

    • 当我做出改变时,我得到一个关于类型转换的错误 'org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type java.lang.Long for价值 'com.security.Institution@27d1fda1';嵌套异常是 java.lang.NumberFormatException: For input string: "com.security.Institution@27d1fda1"' 我的用户有一个机构属性,我的下拉列表属于该类型 - 所以不确定它为什么不设置对象
    • 当您在现场机构中发送表单时,您发送 Insitution 的名称,并且在您的用户中,您有一个机构类的属性,然后 Spring 尝试从 DB 中恢复实体,但它不能因为 Spring有一个字符串,机构的 id 是长的。
    • [继续] 首先您需要返回机构的 Id 值: th:value="${dropDownItem.id}" (或 id 属性的名称)并且在您的应用程序中您需要有一个将类从 String 转换为机构,在此转换中,您可以将 String 转换为 Long 并使用您的机构存储库来获取机构。
    • 非常感谢,我从未听说过 Convert 类。我想我期待该机构以 JSON 或对象或其他东西的形式回来。效果很好,感谢您的解释和时间!
    猜你喜欢
    • 1970-01-01
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 2017-10-06
    相关资源
    最近更新 更多