Freemarker NonHashException: 如何正確訪問模板中的對象屬性

Freemarker NonHashException: 如何正確訪問模板中的對象屬性

第一段引用上面的摘要

本文旨在解決在使用 apache Freemarker 模板引擎時遇到的 NonHashException 異常,該異常通常發生在嘗試訪問對象屬性時,Freemarker 卻將對象識別為字符串。通過分析問題原因和提供解決方案,幫助開發者正確地在 Freemarker 模板中訪問和使用對象屬性,避免類型不匹配導致的錯誤。

在使用 spring Boot 和 Apache Freemarker 構建 Web 應用時,經常需要將 Java 對象傳遞到 Freemarker 模板中進行渲染。然而,有時會遇到 freemarker.core.NonHashException 異常,提示 “Expected a hash, but this has evaluated to a String”。 這通常發生在試圖通過點號(.)訪問對象屬性時,Freemarker 引擎錯誤地將該對象識別為字符串。

問題分析

Freemarker 模板引擎對數據類型的處理與 Java 有所不同。當你在模板中使用點號(.)訪問對象屬性時,Freemarker 期望左側的操作數是一個哈希表(Hash),也就是一個可以像 map 一樣通過鍵值對訪問數據的對象。 如果 Freemarker 認為左側的操作數是一個字符串,就會拋出 NonHashException 異常。

例如,假設你有一個 Java 類 TicketSearchForm,包含一個 status 屬性:

import lombok.Data;  @Data public class TicketSearchForm {     private String status = "ALL";     //More fields... }

你將 TicketSearchForm 對象 previousSearch 傳遞到 Freemarker 模板中,并嘗試使用以下代碼進行比較:

<#if previousSearch.status.equals("ALL")>selected</#if>

這段代碼在 Java 中是完全有效的,但是在 Freemarker 中卻可能拋出 NonHashException 異常。

解決方案

問題的根源在于 Freemarker 處理字符串的方式與 Java 不同。在 Freemarker 中,字符串比較應該使用 == 運算符,而不是 equals() 方法。

因此,正確的 Freemarker 代碼應該如下所示:

<#if previousSearch.status == "ALL">selected</#if>

將 equals() 方法替換為 == 運算符后,Freemarker 就可以正確地比較字符串,避免 NonHashException 異常。

示例代碼

以下是一個完整的示例,展示了如何在 Freemarker 模板中使用 == 運算符比較字符串:

在這個例子中,previousSearch.status 屬性的值將與 “ALL”、”OPEN” 和 “DONE” 進行比較,如果匹配,則對應的

注意事項

  • 字符串比較: 在 Freemarker 中,始終使用 == 運算符進行字符串比較,而不是 equals() 方法。
  • 對象屬性訪問: 確保傳遞到 Freemarker 模板中的對象屬性是可訪問的,并且具有正確的類型。
  • 數據模型: 仔細檢查傳遞到 Freemarker 模板中的數據模型,確保包含所有需要的屬性,并且屬性名稱正確。
  • 異常信息: 仔細閱讀 Freemarker 拋出的異常信息,通常可以提供有關問題的線索。

總結

NonHashException 異常是 Freemarker 中常見的錯誤,通常是由于字符串比較方式不正確導致的。通過使用 == 運算符代替 equals() 方法,可以有效地解決這個問題。此外,還需要注意對象屬性的訪問權限和數據模型的正確性,以確保 Freemarker 模板能夠正確地渲染數據。理解 Freemarker 的數據類型處理方式,是避免此類問題的關鍵。

? 版權聲明
THE END
喜歡就支持一下吧
點贊5 分享