2016-08-04 14 views
0

Ich habe einige Probleme mit einem benutzerdefinierten Zeichensatz aus einer Webanwendung. Der Zeichensatz wird in einer JAR bereitgestellt und Charset.forName("MYCUSTOMCHARSET") funktioniert ohne Probleme von einer Java SE-Anwendung. Innerhalb einer Webanwendung wird diese Methode jedoch UnsupportedCharsetException auslösen.Verwenden Sie benutzerdefinierte Zeichensatz in Webapp

Ich verstehe, dass dies ein Problem von Klassenladeprogrammen ist und ich weiß, dass ich das Problem lösen kann, indem ich das JAR dem Klassenpfad der Servlet-Engine hinzufüge. Aber das ist nicht was ich will. Ich möchte in der Lage sein, eine eigenständige WAR-Datei an meinen Kunden zu liefern, ohne dass der Kunde mit dem umgebenden Container herumspielen muss.

Mit anderen Worten: Ich suche nach einer Methode, die es meiner Webanwendung erlaubt, den Zeichensatz "manuell" zu laden. Von dem Ordner services in der JAR, die den benutzerdefinierten Zeichensatz bereitstellt, kann ich den vollständig qualifizierten Namen des CharsetProviders sehen, z. com.acme.CustomCharsetProvider. Ich frage mich, ob mir das irgendwie hilft?

Plattform: Java 8 und Tomcat 8.

+0

@JordiCastilla. Ich denke, Sie beziehen sich auf die Verwendung von Zeichensätzen im Zusammenhang mit der Codierung/Decodierung von HTTP-Anfragen? Ich spreche von der Verwendung von Zeichensätzen im Allgemeinen, z. zum Codieren/Decodieren eines Strings * innerhalb * der Anwendung selbst. Auch meine Frage ist nicht wirklich spezifisch für Tomcat, obwohl ich mit einer Tomcat-spezifischen Lösung einverstanden bin. – peterh

+1

In der Tat 'META-INF/services/java.nio.charset.spi.CharsetProvider' und dann' for (CharsetProvider charsetProvider: ServiceLoader.load (CharsetProvider.class)) { ... '? –

+0

@ JoopEggen. Vielen Dank. Siehe meine vorgeschlagene Lösung unten. – peterh

Antwort

3

Basierend auf Kommentar oben von Joop ich in der Lage war, mit dem folgenden zu kommen. Die folgende Methode ist der Versuch eines kugelsicheren Rezepts, um immer in der Lage zu sein, den benutzerdefinierten Zeichensatz zu erhalten, egal in welchem ​​Szenario wir uns befinden (z. B. Standalone Java SE-Anwendung, Webapp usw.).

In der Methode wird erwartet, dass der benutzerdefinierte Zeichensatz von Klasse com.acme.CustomCharsetProvider bereitgestellt wird (durch eigene ersetzen).

Das Verfahren verwendet drei verschiedene Versuche halten, die charset zu erhalten:

  1. Standardmethode. Dies funktioniert in Java SE-Anwendungen, aber nicht in Webapps, es sei denn, die JAR, die den benutzerdefinierten Zeichensatz enthält, ist im Klassenpfad der Servlet-Engine verfügbar .
  2. ServiceLoader-Methode. Diese sollte funktionieren, aber nicht in meinem Fall. Kann nicht erklären warum.
  3. Manuelles Instanziieren der Provider-Klasse. (Das funktioniert für mich)

Hier ist der Code:

public static Charset getMyCustomCharset() throws java.nio.charset.UnsupportedCharsetException { 
    Charset customCharset = null; 
    try { 
     // This will fail if running in web container because 
     // the JDK loads charsets using the system class loader in the servlet 
     // engine (e.g. Tomcat) so unless the JAR is available on the engine's 
     // classpath then the charset will not be visible to the webapp. 
     // The solution is to load the charset "manually" as below. 
     customCharset = Charset.forName(CHARSET_NAME); 
    } catch (Exception ex) { 
     // Try to load the charset manually using ServiceLoader concept 
     for (CharsetProvider charsetProvider : ServiceLoader.load(com.acme.CustomCharsetProvider.class)) { 
      customCharset = charsetProvider.charsetForName(CHARSET_NAME); 
      if (customCharset != null) { 
       break; 
      } 
     } 
     // Make a final attempt. This time directly, i.e. without the use of 
     // the ServiceLoader. 
     if (customCharset == null) { 
      com.acme.CustomCharsetProvider p = new com.acme.CustomCharsetProvider(); 
      customCharset = p.charsetForName(CHARSET_NAME); 
     } 
    } 
    if (customCharset == null) { 
     throw new java.nio.charset.UnsupportedCharsetException("Unknown charset : " + CHARSET_NAME); 
    } 
    return customCharset; 
} 
Verwandte Themen