You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring+Freemarker遇NonHashException,无法访问对象属性怎么解决?

解决FreeMarker中previousSearch被识别为字符串无法访问属性的问题

问题原因

出现NonHashException的核心原因是Spring往Model中传递的previousSearch不是TicketSearchForm对象,而是一个字符串。可能的触发场景:

  • Controller中误将TicketSearchForm的toString()结果(或其他字符串值)存入了previousSearch这个Model键;
  • 请求参数中存在同名的previousSearch字符串参数,Spring自动将其绑定到Model,覆盖了你原本存入的对象;
  • 代码中错误地将字符串类型赋值给了previousSearch对应的Model属性。

解决步骤

1. 检查Controller的Model赋值逻辑

确保你往Model中存入的是TicketSearchForm实例,而非字符串。正确示例如下:

@GetMapping("/ticket/search")
public String showSearchPage(Model model) {
    TicketSearchForm previousSearch = new TicketSearchForm();
    // 可从会话/数据库加载历史搜索数据
    model.addAttribute("previousSearch", previousSearch); // 存入对象而非字符串
    return "ticket/search";
}

排查是否存在model.addAttribute("previousSearch", "some-string-value")这类错误代码,或赋值前是否意外将对象转为了字符串。

2. 排查同名请求参数覆盖问题

如果请求URL/表单中存在名为previousSearch的参数,Spring会自动将其作为字符串存入Model,覆盖你手动添加的对象。可以通过以下方式验证:

  • 暂时移除请求中所有previousSearch相关参数,测试模板是否正常运行;
  • 在Controller中打印model.getAttribute("previousSearch")的类型,确认其是否为TicketSearchForm实例。

3. 优化FreeMarker模板写法

FreeMarker可直接通过属性名访问对象的getter(Lombok的@Data已生成getStatus()),无需手动调用get方法,同时用==做字符串对比更简洁:

<select name="status" id="status" class="form-control select2">
    <option value="ALL" <#if previousSearch.status == "ALL">selected</#if>>Alle anzeigen</option>
    <option value="OPEN" <#if previousSearch.status == "OPEN">selected</#if>>Offen</option>
    <option value="DONE" <#if previousSearch.status == "DONE">selected</#if>>Geschlossen</option>
</select>

内容的提问来源于stack exchange,提问作者monamona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:15:29