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