Frage

Ich bin etwas verwirrt mit dem, was in der/den Dokumentation(en) für Freemarker und Restlets Freemarker-Erweiterung geschrieben steht.

Hier ist die Situation:Die Restlet-Engine stellt eine HTML-Darstellung einer Ressource bereit (z. B.www.mysite.com/{user}/updates).Die für diesen URI zurückgegebene Ressource ist eine HTML-Seite mit allen Aktualisierungen, die mit einer Freemarker-Vorlage erstellt wurde.Diese Anwendung wird auf einem Glassfish v3-Server gehostet

Fragen):

  • Die Freemarker-Konfiguration sollte gemäß der Freemarker-Dokumentation nur einmal geladen werden:

        /* You should do this ONLY ONCE in the whole application life-cycle:Create and adjust the configuration */
        Configuration cfg = new Configuration();
        cfg.setDirectoryForTemplateLoading(
                new File("/where/you/store/templates"));
        cfg.setObjectWrapper(new DefaultObjectWrapper());
    

    Was ist der beste Ort, um dies in einer Java EE-App zu tun?Ich denke darüber nach, es als Kontextparameter in web.xml zu haben und einen ServletContextListener zu verwenden – aber ich bin mir nicht sicher, wie ich das machen soll.

  • Gemäß der Dokumentation von Freemarker könnten wir auch ein Freemarker-Servlet und eine Karte hinzufügen .ftl-URL-Muster dazu.Dies wird jedoch bereits durch ein Restlet-Servlet abgebildet (d. h. das URL-Muster von „/").Es macht also keinen Sinn, ein anderes für *.ftl zu haben (oder doch?)

Die Frage ist also im Wesentlichen, wie man sich am besten in die „Konfiguration“ von Freemarker integrieren lässt, sodass es nur einmal vorkommt, und was der „Einstiegspunkt“ für diesen Codeabschnitt ist (wer ihn aufruft).Hat jemand Freemarker + Restlet erfolgreich in einer Java EE-Umgebung verwendet?Irgendwelche Ideen?

Danke!

War es hilfreich?

Lösung

Das war tatsächlich eine knifflige Frage.Ich musste die Implementierung der Quelldateien im Paket org.restlet.ext.Freemarker durchgehen – Puh!

Hier erfahren Sie, wie Sie es tun können

  1. Wenn Sie Ihr EIGENES Konfigurationsobjekt erstellen müssen, legen Sie den zu verwendenden „templateLoader“ fest und lassen Sie dann TemplateRepresentation zum Rendern daran „arbeiten“:

    Configuration cfg = new Configuration();
    
    ContextTemplateLoader loader = new ContextTemplateLoader(getContext(),"war:///WEB-INF");
    
    cfg.setTemplateLoader(loader);
    
    TemplateRepresentation rep = null;
    
    Mail mail = new Mail(); //The data object you wish to populate - example from Restlet itself
        mail.setStatus("received");
        mail.setSubject("Message to self");
        mail.setContent("Doh!");
        mail.setAccountRef(new Reference(getReference(), "..").getTargetRef()
                .toString());
    
      Map<String, Object> data = new HashMap<String, Object>();
      data.put("status", mail.getStatus());
      data.put("subject", mail.getSubject());
      data.put("content", mail.getContent());
      data.put("accountRef", mail.getAccountRef());
    
      rep = new TemplateRepresentation("Mail.ftl", cfg, data, MediaType.TEXT_HTML);
    
      return rep;
    
  2. Wenn Sie mit der Standardeinstellung zufrieden sind und eine auf einem Klassenlader basierende Methode zum Laden der Vorlagen verwenden möchten

    //Load the FreeMarker template
        Representation mailFtl = new ClientResource(
                LocalReference.createClapReference(getClass().getPackage())
                        + "/Mail.ftl").get(); 
      //Wraps the bean with a FreeMarker representation
    return new TemplateRepresentation(mailFtl, mail, MediaType.TEXT_HTML);
    
  3. Wenn Sie das Konfigurationsobjekt initialisieren möchten einmal und legen Sie die Vorlage fest, indem Sie die Methode setServletContextForTemplateLoading(...) für das Konfigurationsobjekt aufrufen.Sie können dies jederzeit in einem ServletContextListener tun


public class Config implements ServletContextListener {
    private static Configuration cfg = new Configuration();

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext sc = sce.getServletContext();
        cfg.setServletContextForTemplateLoading(sc, "/WEB-INF");        
    }
    public static Configuration getFMConfig()
    {
        return cfg;
    }
}

Rufen Sie dann die statische Funktion getFMConfig() auf und übergeben Sie sie wie in 1 an TemplateRepresentation

Zu beachten:

  • Wenn Sie ein Protokoll erhalten, das nicht unterstützt wird, liegt die Ausnahme bei Fall 2 vor.Bedeutet, dass die ServerResource nicht weiß, welches Protokoll sie für den Zugriff auf die Datei verwenden soll – es wird das CLAP-Protokoll von Restlet sein.Möglicherweise müssen Sie die Init-Parameter für RestletServlet in der Datei web.xml einrichten und CLAP als einen der Parameterwerte angeben
  • Die TemplateRepresentation hat einige Konstrukteure - Wenn Sie während der Instanziierung KEIN Konfigurationsobjekt übergeben (mit einem anderen überladenen Konstruktor), wird eine neue Configuration() für Sie erstellt.Sie müssen also keine Konfiguration wie in 2 einrichten. (Das erscheint Ihnen vielleicht offensichtlich, aber ich ging davon aus, dass Sie trotzdem eine Konfiguration einrichten müssten, sonst würde es „irgendwo abholen“).
  • Wenn Sie Ihre EIGENE Konfiguration einrichten möchten, MÜSSEN Sie diese an einen der Konstruktoren übergeben
  • Schauen Sie sich die Zeichenfolge „war:///“ im Konstruktor von ContextTemplateLoader in 1 an. das ist wichtig Nirgendwo wird erwähnt, was das ist baseUri Referenz sollte sein, nicht einmal in den Dokumenten.Ich habe eine ganze Weile versucht, bis ich herausgefunden habe, dass es „war:///“ sein sollte, gefolgt vom Namen des Ordners, in dem die Vorlagen gespeichert sind.
  • Für Fall 2 müssen Sie die Vorlagen wahrscheinlich im selben Paket speichern wie die Klassendatei, von der aus auf diesen Code zugegriffen wird.Wenn Sie genau hinschauen, werden Sie einen LocalReference-Parameter als Argument für ClientResource bemerken, der besagt, dass die Ressource lokal vorhanden sein soll und Sie daher das benutzerdefinierte CLAP-Protokoll (classLoader Access Protocol) verwenden müssen.

Persönlicher Frustrationspunkt - Warum wird das alles nicht einmal in der Dokumentation oder ÜBERALL geklärt? :)

Ich hoffe, es hilft jemandem, der über diesen Beitrag stolpert!Puh!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top