Google App Engine DataStore 文本 UTF-8 编码问题

Posted

技术标签:

【中文标题】Google App Engine DataStore 文本 UTF-8 编码问题【英文标题】:Google App Engine DataStore Text UTF-8 Encoding Problem 【发布时间】:2011-03-09 21:14:24 【问题描述】:

我正在构建一个 gwt 应用程序,它将随机网页的文本存储在数据存储文本字段中。文本通常采用 UTF-8 格式。我的应用程序的所有文件都存储为 UTF-8,当我在本地计算机上运行应用程序时,整个过程都可以正常工作。 UTF-8 文本以 UTF-8 格式存储,并可从应用引擎的本地版本中检索。但是,当我在存储文本和检索文本之间的某个位置将应用程序部署到谷歌应用程序引擎时,它不再是 UTF-8,这会导致非 ascii 字符显示为?。

当我在 appengine 控制面板中查看数据存储时,所有特殊字符都显示为 ?这让我相信这是写入数据库时​​出现的问题。

有谁知道如何解决这个问题?

应用程序本身有点大。 这是一些伪代码:

Text webPageText = new Text(<STRING THAT CONTAINS UNICODE CHARACTERS>);

/*Some Code to store Text object on datastore
Specifically I'm using javax.jdo.PersistenceManager to do this.
Some Code to retrieve text from datastore. */

String retrievedText = webPageText.getValue();

问题是retrieveText 回来了?而不是 unicode 字符。

我在 python 中发现了一个类似的问题:Trying to store Utf-8 data in datastore getting UnicodeEncodeError。虽然我的应用程序没有出现任何错误。

不幸的是,我认为 Java 字符串是默认的 utf-8,我找不到任何可以让我将它们明确声明为 utf-8 的代码。

编辑:我现在构建了一个小型 web 应用程序,它接收 unicode 文本并将其存储在数据存储中,然后毫无问题地检索它。我仍然不知道问题出在我的原始源代码中,但我将更改我的代码处理网页检索的方式,以匹配我刚刚构建的较小的应用程序。谢谢大家的帮助。

【问题讨论】:

你能贴出相关的代码吗? 您说您认为问题出在存储和检索上,那么请不要包含您用于存储和检索数据的代码!如果我们要提供帮助,我们需要相关代码。 整个项目的源码现在贴在上面。几个小时后,我将尝试制作一个重现问题的小版本。 @RichardWallis 请问您找到解决方案了吗?从您遇到此问题 2 年后,仍然有人遇到此问题。 【参考方案1】:

毕竟,这些链接可能很有用:

How to set Google App Engine java Content-Type to UTF-8

http://code.google.com/appengine/docs/python/tools/webapp/buildingtheresponse.html

【讨论】:

我不太了解python,但我认为这些并不是我想要的。我只提供 1 个也是 UTF-8 的网页,我可以在客户端和服务器之间发送 UTF-8 文本。只有在从 appengine 数据存储区存储/检索 UTF-8 文本时才会出现唯一的问题。 我上面的陈述可能不正确。我不确定是否可以在客户端和 appengine 服务器之间发送 UTF-8 文本。明天会检查这个。【参考方案2】:

我尝试将 String 转换为 ByteArray,然后将其存储为数据存储 blob。

//Save String as Blob
Blob webPageText = new Blob(<STRING THAT CONTAINS UNICODE CHARACTERS>.getBytes());

//Retrieve Blob as String
String retrievedText = new String(webPageText.getBytes());

我最初认为这已经解决了问题,但我错误地只在我的本地服务器上测试了它。此代码仍然返回?而不是 unicode 字符,这让我相信问题不在于数据存储区,而在于从应用引擎到客户端的传输。

【讨论】:

这是您问题的实际答案吗?如果是,请接受。【参考方案3】:

通过将请求和响应编码都设置为 utf-8 来修复相同的问题。 请求编码导致存储在数据存储中的有效字符串,没有它的值将存储为“????...”

请求:如果您使用 Apache HTTP 客户端,则通过以下方式完成:

获取请求:

NameValuePair... params;
...
String url = urlBase + URLEncodedUtils.format(Arrays.asList(params), "UTF-8");
HttpGet httpGet = new HttpGet(url);

发布请求:

NameValuePair... params;
...
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(Arrays.asList(params), "UTF-8"));

响应:如果您在 HttpServlet 中构建响应,则通过以下方式完成:

HttpServletResponse resp;
...
resp.setContentType("text/html; charset=utf-8");

【讨论】:

【参考方案4】:

编码解决方案:导致浏览器使用"8859_1" charset => 之前 保存数据存储,我转换字符集。

new String(req.getParameter("title").getBytes("8859_1"),"utf-8")

当我在本地计算机上运行此应用程序时,一切正常。但是当我部署时,我遇到了你看到的同样的问题。我通过以下方式解决了这个问题:

之后 => 保存数据存储代码。

new String(req.getParameter("title").getBytes("utf-8"),"utf-8")

【讨论】:

以上是关于Google App Engine DataStore 文本 UTF-8 编码问题的主要内容,如果未能解决你的问题,请参考以下文章

Google Cloud 中的 Google Compute Engine、App Engine 和 Container Engine 有啥区别?

连接 Google App Engine 和 Google Compute Engine

Google App Engine Flexible 和 Google Container Engine 之间的区别?

如何在 Google Cloud App Engine 上使用 PubSub 创建订阅者,该订阅者通过 Publisher 从 Google Cloud App Engine Flex 收听消息?

将 Meteor 部署到 Google App Engine 2017

Google BigQuery 的 Google App Engine 授权