我在使用webapp的自定义字符集时遇到了一些麻烦。 charset在JAR中提供,Charset.forName("MYCUSTOMCHARSET")
在Java SE应用程序中没有问题。但是,从webapp中,此方法将抛出UnsupportedCharsetException
。
我知道这是类加载器的问题,我知道我可以通过将JAR添加到servlet引擎的类路径来解决问题。但这不是我想要的。我希望能够向客户提供一个独立的WAR文件,而无需客户摆弄周围的容器。
换句话说:我正在寻找一种方法,允许我的webapp“手动”加载字符集。从提供自定义字符集的JAR中的services
文件夹中,我可以看到CharsetProvider的完全限定名称,例如com.acme.CustomCharsetProvider
。我想知道这会不会对我有所帮助?
平台:Java 8和Tomcat 8。
答案 0 :(得分:3)
基于Joop的上述评论,我能够提出以下建议。下面的方法是尝试使用防弹配方,无论我们处于什么场景(例如独立的Java SE应用程序,webapp等),总是能够掌握自定义字符集。
在方法中,自定义字符集应由类com.acme.CustomCharsetProvider
提供(替换为您自己的字符集)。
该方法使用三种不同的尝试来获取字符集:
以下是代码:
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;
}