Android 将请求/响应编码设置为UTF-8,以在app engine数据存储中存储文本

Android 将请求/响应编码设置为UTF-8,以在app engine数据存储中存储文本,android,google-app-engine,encoding,utf-8,google-cloud-endpoints,Android,Google App Engine,Encoding,Utf 8,Google Cloud Endpoints,在我的android应用程序中,我将一些数据保存在本地文件系统中,并检索这些数据以显示在android活动中。我使用UTF-8格式来存储文本,因此我能够以多种语言保存和显示文件。这个很好用。我的应用程序也连接到谷歌应用程序引擎,我正在使用谷歌应用程序引擎数据存储来存储一些数据。在某些情况下,我会将文本保存到app engine数据存储中,然后将其检索回来。在这个过程中,我注意到在保存时无法为测试指定UTF-8编码。是否有任何方法可以确保在保存和从app engine数据存储检索文本的过程中使用U

在我的android应用程序中,我将一些数据保存在本地文件系统中,并检索这些数据以显示在android活动中。我使用UTF-8格式来存储文本,因此我能够以多种语言保存和显示文件。这个很好用。我的应用程序也连接到谷歌应用程序引擎,我正在使用谷歌应用程序引擎数据存储来存储一些数据。在某些情况下,我会将文本保存到app engine数据存储中,然后将其检索回来。在这个过程中,我注意到在保存时无法为测试指定UTF-8编码。是否有任何方法可以确保在保存和从app engine数据存储检索文本的过程中使用UTF-8格式

下面添加了数据存储插入操作的示例代码

    public class EndpointsInsertUpdateQuizContentTask extends AsyncTask<Context, Integer, Long>{
    protected Long doInBackground(Context... contexts){
        Quizcontenttableendpoint.Builder endpointBuilder = new Quizcontenttableendpoint.Builder(
        AndroidHttp.newCompatibleTransport(), new JacksonFactory(), new HttpRequestInitializer() {
        public void initialize(HttpRequest httpRequest) { } });
        Quizcontenttableendpoint endpoint = CloudEndpointUtils.updateBuilder(endpointBuilder).build();
        try{
            //get local file content into a string
            int ch;
            StringBuffer fileContent = new StringBuffer("");
            FileInputStream fis;
            //String quizContentString;
            fis = getBaseContext().openFileInput(selectedQuiz);
            while( (ch = fis.read()) != -1)
                fileContent.append((char)ch);
            String quizContentString = new String(fileContent);

                QuizContentTable quizContentTable = new QuizContentTable();
                quizContentTable.setQuizKey(quizKey);
                quizContentTable.setQuizContent(quizContentString);

                quizContentResult = endpoint.insertQuizContentTable(quizContentTable).execute();
        }   
        catch(Exception e){
            errMsg=e.toString();}
        return (long) 0;
    }
    private ProgressDialog pdia;
    @Override
    protected void onPreExecute(){ 
        super.onPreExecute();
        pdia = new ProgressDialog(ctx);
        pdia.setMessage("Loading");
        pdia.show();    
    }
    protected void onPostExecute(Long result1) {
        pdia.dismiss();

}
公共类EndpointsUserTupDateQuizContentTask扩展了AsyncTask{
受保护的长doInBackground(上下文…上下文){
Quizcontenttableendpoint.Builder endpointBuilder=新的Quizcontenttableendpoint.Builder(
AndroidHttp.newCompatibleTransport(),new JacksonFactory(),new HttpRequestInitializer(){
公共无效初始化(HttpRequestHttpRequest){};
Quizcontenttableendpoint=CloudEndpointUtils.updateBuilder(endpointBuilder.build();
试一试{
//将本地文件内容转换为字符串
int-ch;
StringBufferFileContent=新的StringBuffer(“”);
文件输入流fis;
//字符串quizContentString;
fis=getBaseContext().openFileInput(SelectedQuike);
而((ch=fis.read())!=-1)
追加((char)ch);
String quizContentString=新字符串(fileContent);
QuizContentTable QuizContentTable=新的QuizContentTable();
setQuizKey(quizKey);
setQuizContent(quizContentString);
quizContentResult=endpoint.insertQuizContentTable(quizContentTable.execute();
}   
捕获(例外e){
errMsg=e.toString();}
返回(长)0;
}
私家侦探;
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
pdia=新进度对话框(ctx);
pdia.setMessage(“加载”);
pdia.show();
}
PostExecute上受保护的void(长结果1){
pdia.discouse();
}

我在其他stackoverflow查询中搜索了类似的问题,其中一些在请求和响应过程中暗示要设置UTF-8编码。我不确定在我的android应用程序中该在哪里设置。在appengine代码中,我只能指定/编辑实体和相应字段及其数据类型。然后我生成相应的e我的项目中的nd点库。我在哪里设置应用引擎请求/响应的编码?

文本字符串作为unicode字符串存储在应用引擎数据存储中,因此不适用字节编码

例如,请参见,--短文本字符串(最多500个unicode字符)映射到
java.lang.string
(因此,为unicode)并可以编制索引;长文本字符串(无法编制索引)映射到并存储为unicode

然而,虽然数据存储支持Unicode,因此直接支持文本,但HTTP要求使用字节,因此需要正确的编码来发送,并在接收时进行解码(因此需要内容类型头中的
字符集=
部分)。具体来说,在HTTP中(请求和响应),编码被指定为内容类型标题的一部分:例如

Content-Type: text/plain; charset=utf-8
在一个servlet中,例如在App Engine Java运行时中使用的servlet,您可以通过调用
ServletResponse
setContentType
setCharacterEncoding
方法来设置该头文件,请参见例如

正如OP在评论中澄清的那样:

要存储在[[
text
]]字段中的非英语文本,但 如果将其显示回原处,则非英语文本将丢失并显示在中 某种奇怪的方式[[在应用程序引擎控制台中查看]]

问题的可能原因是,发送到App Engine的请求未正确序列化为UTF8字节,且未使用上文指定的
内容类型

当然,标题仅适用于请求的正文。要将Unicode文本作为查询字符串的一部分发送(例如,在HTTP
GET
中),每个字符串的进一步
%HH
编码(UTF-8编码)字节是必需的。例如,要发送зачааааааааааааааааааааааа1072

http://appid.appspot.com/x?y=%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5

解决了此问题。问题是我在将文件内容读入字符串时遗漏了UTF编码。将上面代码中的文件读取部分替换为下面的代码


在这种情况下,为什么任何多语言(非英语但支持Unicode)文本不能正确显示在数据存储中。我可以使用app engine控制台查看存储的数据,我可以看到语言编码正在丢失。感谢Alex的解释。但我的查询仍然存在。我将一些文本存储为数据类型“text”在我的实体中。据我所知,它应该以Unicode格式存储和检索。在这种情况下,如果我将任何支持Unicode的语言作为该字段的内容传递,那么它应该在我的应用程序中以相同的方式显示。然而,我注意到,我正在输入一些非英语文本以存储在该字段中,但在显示时,非英语文本h文本丢失并以某种奇怪的方式显示,例如“a¨a¥”@user1938357,您是否在发送给App Engine的请求中设置了正确的内容类型标头,并对该文本进行了适当的序列化?文本确实以Unicode(数据存储支持该格式)存储和检索,但HTT
          String str;
            StringBuffer fileContent = new StringBuffer("");
            BufferedReader in = new BufferedReader(new InputStreamReader(getBaseContext().openFileInput(selectedQuiz), "UTF-8"));
            while ((str = in.readLine()) != null)
                fileContent.append(str);
            String quizContentString = new String(fileContent);
            in.close();