添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Thymeleaf has strange ways of binding data. If I use a command object to back a form, and try access its properties for conditional checks, then there is no neat way to work with properties of Enum types.

I have a simple search function, which accepts an input code and searches for a stock index in database. If the index is found, then I will suggest the user to browse its corresponding stock components, otherwise I would suggest the user to initialize the index via scraping services.

Now, my search result is a simple POJO, which looks like following.

public class IndexesSearchObject { private String searchCode; private String searchResult; private ESearchStatus searchStatus;

The search status is straightforward as well.

public enum ESearchStatus { FOUND, NOTFOUND

Section of the controller looks like this:

@RequestMapping(value="/statics/indexes/search", method=RequestMethod.POST, params="search") public String indexesSearch(@ModelAttribute IndexesSearchObject indexesSearchObject, @ModelAttribute Index index, BindingResult bindingResult, Model model){ if(indexService.existsByCode(indexesSearchObject.getSearchCode())){ Index searchedIndex = indexService.getIndexByCode(indexesSearchObject.getSearchCode()); model.addAttribute("indexesObject", searchedIndex); indexesSearchObject.setSearchResult("found 1 record!"); indexesSearchObject.setSearchStatus(ESearchStatus.FOUND); }else{ model.addAttribute("indexesObject", index); indexesSearchObject.setSearchResult("found 0 found!"); indexesSearchObject.setSearchStatus(ESearchStatus.NOTFOUND); model.addAttribute("indexSearchObject", indexesSearchObject); return "statics/indexes/indexform";

The switch case of thymeleaf code works in two method, as far as I dig from internet. Neither of them works on command object property binding.
Method 1: by using Enum directly in switch case (code is very lengthy because is has the full package path on it.)

<!-- search an index --> <form th:object="${indexesSearchObject}" th:action="@{/statics/indexes/search}" method="post"> <input type="text" th:field="*{searchCode}"/> <button type="submit" name="search" value="search">Search</button> <label th:text="*{searchResult}">100 records found</label> <div th:switch="*{searchStatus}"> <p th:case="${T(com.hedge.panda.controllers.statics.command.ESearchStatus).FOUND}"> <button type="submit" name="components" value="components">Components</button> <p th:case="*"> <button type="submit" name="init" value="init">Initialize</button> </form>

Method 2: by converting the Enum to a string, then we get a shorter code.

<!-- search an index --> <form th:object="${indexesSearchObject}" th:action="@{/statics/indexes/search}" method="post"> <input type="text" th:field="*{searchCode}"/> <button type="submit" name="search" value="search">Search</button> <label th:text="*{searchResult}">100 records found</label> <div th:switch="${#strings.defaultString(indexesSearchObject.searchStatus,'')}"> <p th:case="'FOUND'"> <button type="submit" name="components" value="components">Components</button> <p th:case="'NOTFOUND'"> <button type="submit" name="init" value="init">Initialize</button> <p th:case="*"> </form>

Frankly, I would prefer the latter method, because it doesn’t carry the package name, so the code won’t go buggy when I do refactoring. However, it’s pity that I can’t use Enum directly, not to mention that I can’t do property binding like *{searchStatus}.

Reference:
1. https://www.baeldung.com/thymeleaf-enums
2. https://stackoverflow.com/questions/24937441/comparing-the-enum-constants-in-thymeleaf
3. https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#strings