2008-10-24 25 views
7

Hôm nay tôi đã cố gắng di chuyển từ Freemarker sang Tiles2 + Freemarker.Spring + Tiles2 + Freemarker - tích hợp qua Freemarker Servlet hoặc thông qua FreeMarkerViewResolver của Spring?

Mẫu trình gắn nhãn freemarker của tôi sử dụng các macro đến từ spring.ftl.

Nếu tôi cung cấp servlet fremarker trong web.xml, mô hình của tôi hiển thị với freemarker, nhưng các biến mùa xuân cụ thể (tự nhiên) không được điền vào mô hình như lò xo FreemarkerView chịu trách nhiệm cho điều đó.

Nếu tôi định cấu hình DispatcherServlet riêng biệt cho url cụ thể (nói "/ tpl/*") và định cấu hình trình giải quyết freemarker làm trình phân giải chế độ xem mặc định cho servlet đó và cung cấp UrlFilenameViewController làm bộ điều khiển mặc định, các biến mùa xuân đặc biệt được điền vào mô hình, nhưng mô hình của riêng tôi không hiển thị: nó bị ràng buộc như một thuộc tính yêu cầu. Tôi có thể truy cập vào mô hình của mình thông qua $ {Request.mymodel.myvar} nhưng theo cách này tôi phải thay đổi tất cả các mẫu freemarker của mình và tôi thấy một cái gì đó có mùi trong ý tưởng.

Bây giờ giải pháp của tôi là để mở rộng UrlFilenameViewController và thêm mô hình của tôi từ yêu cầu ModelAndView:

protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) { 
     ModelAndView mav = super.handleRequestInternal(request, response); 

     HashMap<String, Object> map = new HashMap<String, Object>(); 

     Enumeration<String> attributes = request.getAttributeNames(); 

     while(attributes.hasMoreElements()) { 
      String attribute = attributes.nextElement(); 

      if("model".equals(attribute)) { 
       logger.debug("FreemarkerViewController.handleRequestInternal: putting attribute to model: " + attribute + "=" + request.getAttribute(attribute)); 
       map.put(attribute, request.getAttribute(attribute)); 
      } 
     } 
     logger.debug("FreemarkerViewController.handleRequestInternal: VIEW: " + mav.getViewName()); 
     return new ModelAndView(mav.getViewName(), map); 
    } 

Nhưng giải pháp này là hơi có mùi quá - nếu tôi thêm một cái gì đó để mô hình trong bộ điều khiển công việc của tôi, tôi phải thêm nó vào đây.

Có giải pháp thanh lịch nào cho vấn đề của tôi không?

+0

Bạn đã bao giờ tìm được giải pháp tốt hơn cho điều này chưa? –

+0

Tôi đang sử dụng nhãn hiệu freleter servlet và taglibs mùa xuân - chúng xử lý mọi thứ tôi đang sử dụng thông qua các macro freemarker mùa xuân đặc biệt. – miceuz

+0

Liên quan đến http://stackoverflow.com/questions/221178/can-anyone-point-me-to-spring-mvc-tiles-freemarker-integration-example – Nick

Trả lời

1

Tôi nhớ tôi đã giải quyết cùng một vấn đề trong hai dự án. Cách tiếp cận thứ hai của bạn gần như đúng (FreeMarkerViewResolver), nhưng nếu tôi nhớ chính xác, tôi cũng phải mở rộng từ FreeMarkerViewTilesView để kết nối cả hai mô hình một cách rõ ràng.

Tuỳ chỉnh Gạch xem:

public class CustomTilesView extends TilesView { 

    @Override 
    protected void exposeModelAsRequestAttributes(Map model, HttpServletRequest request) { 
     request.setAttribute(CustomFreeMarkerView.MODEL_KEY, model); 
    } 
} 

Tuỳ chỉnh Freemarker xem:

public class CustomFreeMarkerView extends FreeMarkerView { 

    public static final String MODEL_KEY = FreeMarkerView.class.getName() + ".MODEL"; 

    @Override 
    protected void exposeHelpers(Map model, HttpServletRequest request) throws Exception { 
     super.exposeHelpers(model, request); 
     final Map savedModel = (Map) request.getAttribute(MODEL_KEY); 
     if (savedModel != null) { 
      mergeModels(model, savedModel); 
     } 
    } 

    private void mergeModels(Map<String, Object> targetModel, Map<String, Object> recipientModel) throws ServletException { 
     for (Map.Entry<String, Object> entry : recipientModel.entrySet()) { 
      String key = entry.getKey(); 
      if (targetModel.containsKey(key)) { 
       throw new ServletException("Cannot merge models because of an existing model object of the same name: " + key); 
      } 
      targetModel.put(key, entry.getValue()); 
     } 
    } 
} 

Đăng ký cả trong mùa xuân:

<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" 
     p:viewClass="com.my.CustomTilesView" 
     p:contentType="text/html;charset=UTF-8"/> 

<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver" 
     p:suffix=".ftl" 
     p:exposeSpringMacroHelpers="true" 
     p:viewClass="com.my.CustomFreeMarkerView" 
     p:contentType="text/html;charset=UTF-8"/> 

nên làm việc.

Các vấn đề liên quan