在webapp中使用自定义字符集

时间:2016-08-04 10:54:53

标签: java servlets character-encoding

我在使用webapp的自定义字符集时遇到了一些麻烦。 charset在JAR中提供,Charset.forName("MYCUSTOMCHARSET")在Java SE应用程序中没有问题。但是,从webapp中,此方法将抛出UnsupportedCharsetException

我知道这是类加载器的问题,我知道我可以通过将JAR添加到servlet引擎的类路径来解决问题。但这不是我想要的。我希望能够向客户提供一个独立的WAR文件,而无需客户摆弄周围的容器。

换句话说:我正在寻找一种方法,允许我的webapp“手动”加载字符集。从提供自定义字符集的JAR中的services文件夹中,我可以看到CharsetProvider的完全限定名称,例如com.acme.CustomCharsetProvider。我想知道这会不会对我有所帮助?

平台:Java 8和Tomcat 8。

1 个答案:

答案 0 :(得分:3)

基于Joop的上述评论,我能够提出以下建议。下面的方法是尝试使用防弹配方,无论我们处于什么场景(例如独立的Java SE应用程序,webapp等),总是能够掌握自定义字符集。

在方法中,自定义字符集应由类com.acme.CustomCharsetProvider提供(替换为您自己的字符集)。

该方法使用三种不同的尝试来获取字符集:

  1. 标准方法。这将在Java SE应用程序中有效,但不适用于 webapps除非拥有自定义字符集的JAR可用 在servlet引擎的类路径上。
  2. ServiceLoader方法。这个应该工作,但不是我的情况。无法解释原因。
  3. 手动实例化提供程序类。 (这对我有用)
  4. 以下是代码:

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