【问题标题】:Java Character Encoding on Google App EngineGoogle App Engine 上的 Java 字符编码
【发布时间】:2015-07-18 03:00:07
【问题描述】:

我在 Google App Engine 上运行一个 GWT 应用程序,它通过 GWT-RPC/Servlet 将来自 GUI 的文本输入传递给 API。但是像 ä,ö,ü 这样的变音符号会被 API 误解,并且 API 只显示 ?而不是变音符号。

我很确定问题出在 Google App Engine 上的默认字符编码,即 US-ASCII:US-ASCII 不知道任何变音符号。

在我的本地机器上使用来自 JUnit-Tests 的 API 变音符号可以工作。那里的默认字符编码是UTF-8。

问题不是来自 GWT 或任何 HTML 文件的编码;我在包含一些变音符号的应用程序中使用了一个常量 Java 字符串并将其传递给 API:如果应用程序部署在 Google App Engine 中,则会出现问题。

有什么方法可以更改 Google App Engine 中的字符编码?或者有人知道我的问题的另一种解决方案吗?

将 GUI 中的变音符号存储在 GAE 数据存储中并将它们带回 GUI 非常有趣。

【问题讨论】:

  • 不清楚您所说的“API 仅显示一个?”是什么意思- 在哪里?理想情况下,您应该跟踪每个阶段的确切数据,以准确找出问题所在。见codeblog.jonskeet.uk/2014/01/20/…
  • 听起来您需要控制输出的字符编码。有关详细信息,请参阅stackoverflow.com/questions/11907764/…
  • @DanielTung 我尝试同时设置<system-properties><property name="file.encoding" value="UTF-8" /><property name="DEFAULT_ENCODING" value="UTF-8" /></system-properties> <env-variables><env-var name="DEFAULT_ENCODING" value="UTF-8" /></env-variables>,但没有成功。
  • @JonSkeet 简而言之:运行 API.call("test äöü") 将导致 API(它发送 SMS)从我的机器发送“test äöü”和“test ???”来自 GAE。
  • @AndréJanus:这并不能真正帮助我们找出问题所在。它是什么 API?你有文件吗?

标签: java google-app-engine gwt character-encoding


【解决方案1】:

我遇到了同样的问题:部署到 Google App Engine 的网络应用程序的默认字符集设置为 US-ASCII,但我需要它是 UTF-8

摸了摸头,我发现添加了:

<system-properties>
    <property name="appengine.file.encoding" value="UTF-8" />
</system-properties>

to appengine-web.xml 正确地将字符集设置为UTF-8。更多详情请见Google Issue Tracker - Setting of default encoding

【讨论】:

    【解决方案2】:

    解决方法(安全)

    我编写了这个类来将 UTF-Strings 编码为 ASCII-Strings(用它们的表号替换所有不在 ASCII 表中的字符,前后加一个标记),使用AsciiEncoder.encode(yourUtfString)

    然后可以使用支持 UTF 的AsciiEncoder.decode(yourAsciiEncodedUtfString) 将字符串解码回 UTF

    package <your_package>;
    
    import java.util.ArrayList;
    
    /**
     * Created by Micha F. aka Peracutor.
     * 04.06.2017
     */
    
    public class AsciiEncoder {
    
        public static final char MARK = '%'; //use whatever ASCII-char you like (should be occurring not often in regular text)
    
        public static String encode(String s) {
            StringBuilder result = new StringBuilder(s.length() + 4 * 10); //buffer for 10 special characters (4 additional chars for every special char that gets replaced)
            for (char c : s.toCharArray()) {
                if ((int) c > 127 || c == MARK) {
                    result.append(MARK).append((int) c).append(MARK);
                } else {
                    result.append(c);
                }
            }
            return result.toString();
        }
    
        public static String decode(String s) {
            int lastMark = -1;
            ArrayList<Character> chars = new ArrayList<>();
            try {
                //noinspection InfiniteLoopStatement
                while (true) {
                    String charString = s.substring(lastMark = s.indexOf(MARK, lastMark + 1) + 1, lastMark = s.indexOf(MARK, lastMark));
                    char c = (char) Integer.parseInt(charString);
                    chars.add(c);
                }
            } catch (IndexOutOfBoundsException | NumberFormatException ignored) {}
    
            for (char c : chars) {
                s = s.replace("" + MARK + ((int) c) + MARK, String.valueOf(c));
            }
            return s;
        }
    }
    

    希望这对某人有所帮助。

    【讨论】:

      【解决方案3】:

      如果您(像我一样)在 Google AppEngine 上使用 Java flexible environment,则可以通过您的 app.yaml 设置 file.encoding 系统属性“简单地”修复默认编码(通过 environment variable 即由运行时自动拾取)像这样:

      env_variables:
        JAVA_USER_OPTS: -Dfile.encoding=UTF-8
      

      【讨论】:

        猜你喜欢
        • 2011-11-05
        • 1970-01-01
        • 2016-03-10
        • 1970-01-01
        • 1970-01-01
        • 2010-10-23
        • 2018-01-23
        • 2012-02-16
        • 2012-09-03
        相关资源
        最近更新 更多