2012-11-08 35 views
7

tôi có thể thành công được điều này để làm việc với các mẫu trong ứng dụng của tôi:Facelets Lấy mẫu/tập tin từ một hệ thống tập tin bên ngoài hoặc cơ sở dữ liệu

<ui:decorate template="/WEB-INF/templates/mytemplate.xhtml"> 

Tôi cũng có thể di chuyển mẫu để /META-INF/templates/mytemplate.xhtml của một JAR và làm việc này:

<ui:decorate template="/templates/mytemplate.xhtml"> 

Tôi thực sự muốn đặt tệp này lên hệ thống tệp (hoặc cơ sở dữ liệu cho vấn đề đó). Làm thế nào tôi có thể đạt được điều này? Tôi đã tìm thấy rất nhiều thứ liên quan đến com.sun.facelets.impl.DefaultResourceResolver, nhưng tôi không nghĩ rằng điều đó thực sự liên quan đến việc ghi đè việc phân phối mẫu. Nó không phải là cố gắng giải quyết một URL, nó chỉ đơn giản là cố gắng để có được các tập tin bằng cách nào đó trên classpath.

Trả lời

12

Nếu bạn đã ở trên JSF 2.2, bạn có thể thực hiện việc này bằng cách cung cấp tùy chỉnh ResourceHandler trong đó bạn trả lại tài nguyên chế độ xem mong muốn trong createViewResource().

public class FaceletsResourceHandler extends ResourceHandlerWrapper { 

    private ResourceHandler wrapped; 

    public FaceletsResourceHandler(ResourceHandler wrapped) { 
     this.wrapped = wrapped; 
    } 

    @Override 
    public ViewResource createViewResource(FacesContext context, final String name) { 
     ViewResource resource = super.createViewResource(context, name); 

     if (resource == null) { 
      resource = new ViewResource() { 
       @Override 
       public URL getURL() { 
        try { 
         return new File("/some/base/path", name).toURI().toURL(); 
        } catch (MalformedURLException e) { 
         throw new FacesException(e); 
        } 
       } 
      }; 
     } 

     return resource; 
    } 

    @Override 
    public ResourceHandler getWrapped() { 
     return wrapped; 
    } 

} 

nào được đăng ký tại faces-config.xml như sau:

<application> 
    <resource-handler>com.example.FaceletsResourceHandler</resource-handler> 
</application> 

Hoặc nếu bạn không trên JSF 2.2 chưa, sau đó sử dụng ResourceResolver để thay thế.

public class FaceletsResourceResolver extends ResourceResolver { 

    private ResourceResolver parent; 

    public FaceletsResourceResolver(ResourceResolver parent) { 
     this.parent = parent; 
    } 

    @Override 
    public URL resolveUrl(String path) { 
     URL url = parent.resolveUrl(path); // Resolves from WAR. 

     if (url == null) { 
      try { 
       url = new File("/some/base/path", path).toURI().toURL(); 
      } catch (MalformedURLException e) { 
       throw new FacesException(e); 
      } 

     } 

     return url; 
    } 

} 

nào được đăng ký tại web.xml như sau:

<context-param> 
    <param-name>javax.faces.FACELETS_RESOURCE_RESOLVER</param-name> 
    <param-value>com.example.FaceletsResourceResolver</param-value> 
</context-param> 

Bất kể đường đi, để cung cấp các nguồn lực từ các cơ sở dữ liệu, bạn muốn thể lưu/bộ nhớ cache chúng trên (tạm thời) hệ thống tệp đĩa để bạn có thể cung cấp URL chỉ qua File hoặc phát minh giao thức tùy chỉnh như db:// và cung cấp triển khai URLStreamHandlerFactoryURLStreamHandler tùy chỉnh để thực hiện công việc thực tế của luồng ing từ DB. Bạn có thể tìm thấy một ví dụ kickoff ở đây Registering and using a custom java.net.URL protocol.

+0

Xin chào BalusC..Điều này đã giúp tôi bắt đầu. Tôi dường như làm việc tốt với các trang .xhtml thực tế. Nhưng nó không có vẻ là làm việc với việc sử dụng các mẫu. Tôi chỉnh sửa câu hỏi để hiển thị lỗi hiện tại tôi đang nhận được. – JeffJak

+0

Tệp có vẻ không tồn tại. Mở rộng ví dụ kickoff để sử dụng 'File # exists()' test và trả về 'null' khi nó không. – BalusC

+0

Tôi đã tìm ra sự cố ... Giải pháp của bạn không hoạt động. Nhưng nó phụ thuộc vào cách tôi xác định mẫu. Ví dụ: nếu tôi sử dụng template = "myfile.xhtml" thì nó sẽ thất bại. Nhưng nếu tôi làm template = "/ myfile.xhtml" thì nó sẽ được đưa vào ResourceResolver. – JeffJak

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