2013-08-04 127 views
3

根據文檔,您應該能夠將javabean傳遞給FreeMarker模板,並且它將能夠訪問bean的getter。我一直在努力做到這一點,但一直沒有任何運氣。這裏是我將代碼傳遞給模板的代碼。FreeMarker無法訪問javabean的屬性

public class Hello extends HttpServlet { 
    public static final Logger LOGGER = Logger.getLogger(Hello.class.getName()); 

    @Override 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
     try { 
      Configuration cfg = new Configuration(); 
      cfg.setDirectoryForTemplateLoading(new File(this.getServletContext().getRealPath("/templates"))); 
      cfg.setObjectWrapper(new DefaultObjectWrapper()); 
      cfg.setDefaultEncoding("UTF-8"); 
      cfg.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER); 
      cfg.setIncompatibleImprovements(new Version(2, 3, 20)); // FreeMarker 2.3.20 

      final String name = req.getParameter("name"); 
      // This works when model is a Map, but not when it is a bean 
      Model model = new Model(); 
      model.setUsername(name); 
      Template template = cfg.getTemplate("hello.ftl"); 
      template.process(model, resp.getWriter()); 
     } catch (TemplateException ex) { 
      LOGGER.log(Level.SEVERE, "Unexpected template exception", ex); 
      resp.sendError(500); 
     } 
    } 

    private static class Model { 
     private String username; 

     public void setUsername(String username) { 
      this.username = username; 
     } 

     public String getUsername() { 
      return username; 
     } 

    } 
} 

當我嘗試訪問${username}在模板中,我得到以下錯誤。

The following has evaluated to null or missing: 
==> username [in template "hello.ftl" at line 8, column 10] 

Tip: If the failing expression is known to be legally null/missing... (snip) 

The failing instruction (FTL stack trace): 
---------- 
==> ${username} [in template "hello.ftl" at line 8, column 8] 
---------- 

我可以讓模板在我使用地圖時正常工作。我試着用各種TemplateModel包裝明確地包裝模型對象,但我沒有嘗試似乎工作。

任何提示?

回答

4

Model必須是公共課才能使用。

與問題無關的一些其他註釋:使用setServletContextForTemplateLoading而不是setDirectoryForTemplateLoading,否則如果從解壓後的.war運行,您的應用將無法工作。此外,當然,您不得爲每個請求重新創建Configuration,但我認爲這僅僅是爲了這個示例。

+0

這解決了它。我檢查了FreeMarker源代碼,他們明確檢查bean是否公開。只有這樣他們纔會嘗試發現公共方法。不知道他們爲什麼這樣做,因爲您可以通過反射來獲取任何對象的公共方法。感謝您的其他提示。知道不重新實例化配置對象,但不知道模板加載。 – haydenmuhl

+0

是的,我不知道爲什麼那裏有限制...我已經加入了這個長長的TODO列表(我是一個FM維護者)。 – ddekany