2012-11-08 7 views
7

Ich bin in der Lage, erfolgreich diese mit der Vorlage in meiner app zu arbeiten:Beziehen Facelets templates/Dateien von einem externen Dateisystem oder Datenbank

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

Ich bin auch in der Lage Vorlage /META-INF/templates/mytemplate.xhtml ein JAR zu bewegen und Holen Sie sich dies zur Arbeit:

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

Ich würde eigentlich gerne diese Datei auf Dateisystem (oder Datenbank für diese Angelegenheit) setzen. Wie kann ich das erreichen? Ich habe viele Dinge gefunden, die mit com.sun.facelets.impl.DefaultResourceResolver zusammenhängen, aber ich denke nicht, dass dies tatsächlich damit zusammenhängt, die Bereitstellung der Vorlage zu überschreiben. Es versucht nicht, eine URL aufzulösen, sondern versucht einfach, die Datei irgendwie auf den Klassenpfad zu bekommen.

Antwort

12

Wenn Sie bereits JSF 2.2 verwenden, können Sie dies tun, indem Sie eine benutzerdefinierte ResourceHandler angeben, in der Sie die gewünschte Ansichtsressource in createViewResource() zurückgeben.

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; 
    } 

} 

Welche wie unten in faces-config.xml registriert ist:

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

Oder wenn Sie nicht auf JSF sind 2.2 noch, dann ResourceResolver stattdessen verwenden.

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; 
    } 

} 

Welche wie unten in web.xml registriert ist:

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

Unabhängig von der Art und Weise, um die Ressource aus der Datenbank zur Verfügung zu stellen, würden Sie entweder speichern/cache sie auf (Temp) Disk-Dateisystem, so können Sie die URL nur über File bereitstellen, oder erfinden Sie ein benutzerdefiniertes Protokoll wie db:// und bieten eine benutzerdefinierte URLStreamHandlerFactory und URLStreamHandler Implementierung, um den eigentlichen Job von Stream durchzuführen aus der DB. Sie können hier ein Kickoff-Beispiel finden Registering and using a custom java.net.URL protocol.

+0

Hallo BalusC..Dies ist mir geholfen, mich zu starten. Es scheint mir gut zu sein, tatsächliche .xhtml-Seiten zu bekommen. Aber es scheint nicht mit der Verwendung der Vorlage zu arbeiten. Ich bearbeite die Frage, um den aktuellen Fehler zu zeigen, den ich jetzt bekomme. – JeffJak

+0

Die Datei existiert anscheinend nicht. Erweitern Sie das Kickoff-Beispiel, um den Test 'File # exists()' zu verwenden, und geben Sie 'null' zurück, wenn dies nicht der Fall ist. – BalusC

+0

Ich habe das Problem herausgefunden ... Ihre Lösung funktioniert. Aber es hängt davon ab, wie ich die Vorlage definiere. Wenn ich beispielsweise template = "myfile.xhtml" verwende, wird es fehlschlagen. Aber wenn ich template = "/ myfile.xhtml" mache, wird es in den ResourceResolver gelangen. – JeffJak

Verwandte Themen