Lokalisierte Bilder in der JSF 2.0-Anwendung

8

Ich habe eine JSF 2.0-Anwendung, mit der der Benutzer die Sprache der Website ändern kann, die sowohl Texte als auch Bilder betreffen soll.

Momentan ist das Gebietsschema in einer Session-Bean festgelegt und jede Seite hat ein Gebietsschema, das aus dieser Session-Bean gesetzt wurde. Es funktioniert hervorragend für Texte. Aber ich habe Probleme mit Bildern. Derzeit verwenden wir Bilder wie folgt:

%Vor%

Dies führt zur Generierung des folgenden HTML-Codes, der an den Benutzeragenten zurückgegeben wird:

%Vor%

Nehmen wir an, dass der Benutzer die Seite auf Englisch anfordert. Die GET-Anforderung für das obige Bild wird von ResourceHandler.handleResourceRequest () verarbeitet. Es verwendet ViewHandler.calculateLocale (), um das richtige Gebietsschema-Präfix zu identifizieren. Ich habe meinen eigenen ViewHandler mit calculateLocale () implementiert, das das Gebietsschema aus der Benutzersitzung abruft. Dadurch wird eine Ressourceninstanz erstellt, die auf "/ resources / english / img / flag.gif" verweist. Dann ändert der Benutzer sein / ihr Gebietsschema auf Französisch. Wenn die Seite erneut geladen wird, wird die gleiche Bild-URL gerendert und angefordert. Dieses Mal gibt ViewHandler.calculateLocale () Locale.FRENCH an den ResourceHandler zurück, was zur Erstellung einer Ressource mit dem Pfad "/ resources / french / img / flag.gif" führt.

Vor dem Streaming des Bildes gemäß der Spezifikation muss ResourceHandler.handleResourceRequest () Folgendes ausführen:

  

• Rufen Sie Resource.userAgentNeedsUpdate (javax.faces.context.FacesContext) auf. Wenn diese Methode false zurückgibt, muss HttpServletRequest.SC_NOT_MODIFIED an HttpServletResponse.setStatus () übergeben werden, dann muss handleResourceRequest sofort zurückgeben.

Er erkennt, dass die Ressource seit der letzten Browseranfrage nicht aktualisiert wurde - ohne zu berücksichtigen, dass die vorherige Anfrage an diese "logische" URL zu einer anderen "physischen" Ressource auf dem Server führt. Und gibt HTTP 304 zurück, was dazu führt, dass das vorherige englische Bild dem Benutzer erneut angezeigt wird.

Wenn die Seite mit Shift + F5 aktualisiert wird, wird das französische Bild korrekt heruntergeladen, da vom Benutzeragent kein "If-Modified-Since" gesendet wird.

Es gibt immer die Möglichkeit, das Gebietsschema-Präfix manuell mit EL im Bibliotheksnamen wie folgt hinzuzufügen:

%Vor%

Aber ich denke immer noch, dass der frühere Ansatz funktionieren sollte und sauberer ist.

Ich frage mich:

  1. Warum erzeugt JSF kein "src", das den tatsächlichen Pfad zum Bild darstellt, falls wir die Attribute "name" und "library" verwenden? JSF verfügt über alle Informationen, um den vollständigen Pfad für die erste Seitenanforderung zu erstellen - einschließlich der Gebietsschemaform des UIViewRoot (es muss kein eigener ViewHandler implementiert werden). Meine Annahme ist, dass dies daran liegt, dass Ressourcen gemäß der Spezifikation auch in eine JAR im Klassenpfad eingefügt werden können. Immer noch konnte die URL zum Servlet nur zum Abrufen der Klassenpfad-Ressourcen gerendert werden, für die keine direkte URL angegeben werden kann.

  2. Warum gibt die Spezifikation an, dass das generierte Bild "src" -Attribut die Bibliothek enthalten sollte, aber nichts über das Gebietsschema-Präfix sagt (siehe Resource.getReqestPath ())? Der Image-Quellcode wird von Resource.getRequestPath () abgerufen. Wenn das Präfix in der URL enthalten wäre, würden französische und englische Bilder vom Browser nicht als einzelne "modifizierte" Ressource interpretiert.

Irgendwelche Ideen sind willkommen!

    
Irina Marudina 12.08.2011, 07:12
quelle

1 Antwort

2

Sie können genauso gut reguläres HTML <img> -Tag verwenden und Ihren eigenen Pfad erstellen.
Es scheint, dass es am besten ist, einen eigenen Controller zum Auflösen von Pfaden zu erstellen:

%Vor%

Der Localization Controller könnte den Kontextpfad (die Basis-URL der aktuellen Anwendung) folgendermaßen lesen:

%Vor%

ExternalContext liefert auch einen echten Pfadnamen (dh den auf der Festplatte, wenn Sie das explodierte Format verwenden) - siehe getRealPath() Methode, sollten Sie jemals brauchen.

Warum bevorzuge ich diese Methode? Es ist extrem einfach und ziemlich mächtig: man kann Localization Controller nicht nur verwenden, um lokalisierte Objekte wie CSS-Dateien (oder zumindest die wichtigsten Stylesheet-Überschreibungen), clientseitige Skripte und natürlich Bilder bereitzustellen, sondern auch um dynamisch lokalisierbar zu sein Kontext (dh Arrays von übersetzbaren Strings in JavaScript).

Um Ihre spezifischen Fragen zu beantworten:

  1. Die kurze Antwort ist, ich weiß es nicht. Ich würde gerne darüber nachdenken, dass jemand, der diese API entworfen hat, sorgfältig alle Vor- und Nachteile abgewogen hat und die optimale Lösung gewählt hat (obwohl er nicht jeden möglichen Anwendungsfall erfüllt).

  2. Dafür kann ich Ihnen eine präzise Antwort geben. Grundsätzlich sollte korrekt internationalisierte Anwendung kein Bild enthalten, das von Locale abhängen könnte, d. H. Kulturspezifisch sein könnte. Dies ist eine ziemlich idealistische Sicht auf die Welt, aber um ehrlich zu sein, ein Bild zu haben, das tatsächlich von Locale abhängt, sollte ein seltener Fall sein Wenn ich Ihr spezifisches Problem verstanden habe, möchten Sie basierend auf dem aktuellen Gebietsschema eine bestimmte Länderflagge wechseln. Tatsächlich können Sie hier auch bedingtes Rendering verwenden ( render="#{someController.someBooleanMethod}" ) und tatsächlich alle Bildreferenzen gleichzeitig schreiben. Ich weiß, es ist scheiße, aber das ist eine brauchbare Lösung.

Paweł Dyda 12.08.2011 20:07
quelle

Tags und Links