Android应用程序解码来自PHP MySql数据库的JSON响应,没有特殊字符

Posted

技术标签:

【中文标题】Android应用程序解码来自PHP MySql数据库的JSON响应,没有特殊字符【英文标题】:Android app decoding JSON response from PHP MySql database without special characters 【发布时间】:2020-05-02 03:40:41 【问题描述】:

我正在尝试从我的database 中的android app 中检索一些数据,但是一些特殊字符发送不正确。数据实际上首先从我的应用程序发送,存储,然后检索。当我发送它时,数据以正确的方式注册,但在检索时似乎存在编码/解码问题。 为了正确存储数据,我使用了mysqli_set_charset($conn, 'utf8'); 命令,因此数据Situație 4 在发送时存储。 发送数据的 php 代码:

$stmt->bind_result($id, $latitudine, $longitudine, $tip_problema, $data_ora, $ora_catalogare, $validare, $grad_incredere);
                while($stmt->fetch()) 
                    $locatie[] = array (
                            "id_alerta"=>$id,
                            "latitudine"=>$latitudine, 
                            "longitudine"=>$longitudine, 
                            "tip_problema"=>$tip_problema,
                            "data_ora"=>$data_ora,
                            "ora_catalogare"=>$ora_catalogare,
                            "stare_problema"=>$validare,
                            "grad_incredere"=>$grad_incredere
                            );
            $response['error'] = false; 
            $response['message'] = 'Alerte reimprospatate';
            $response['locatie']= $locatie;
                 

我需要的信息存储在 $locatie 中,因此我可以在我的应用程序上获得 JSON 响应。

输入 JSON 响应的应用代码:

@Override
        protected void onPostExecute(String s) 
            super.onPostExecute(s);
            //hiding the progressbar after completion

            try 
                //converting response to json object
                JSONObject obj = new JSONObject(s);

                //if no error in response
                if (!obj.getBoolean("error")) 
                    Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_SHORT).show();

                    JSONArray locatieArray = obj.getJSONArray("locatie");
                    for (int i = 0; i < locatieArray.length(); i++) 
                        JSONObject locatie = locatieArray.getJSONObject(i);
                        // check latitudine and longitudine is not null and if not null then cast these values and call the addMarker() method.
                        if (!locatie.isNull("latitudine") && !locatie.isNull("longitudine")) 
                            latitudine_sql = Double.valueOf(locatie.getString("latitudine"));
                            longitudine_sql = Double.valueOf(locatie.getString("longitudine"));
                            tip_problema_sql = locatie.getString("tip_problema");
                            id = locatie.getString("id_alerta");
                            data_ora_raportare = locatie.getString("data_ora");
                            stare_alarma = locatie.getString("stare_problema");
                            data_ora_ack = locatie.getString("ora_catalogare");
                            grad_incredere = locatie.getString("grad_incredere");
                            addMarker(latitudine_sql, longitudine_sql);

                        
                    

                 else 
                    Toast.makeText(getApplicationContext(), "Some error occurred", Toast.LENGTH_SHORT).show();
                
             catch (JSONException e) 
                e.printStackTrace();
             catch (IOException e) 
                e.printStackTrace();
            
        
    

这里是棘手的部分。 json 响应如下所示:


"error": false,
"message": "Alerte reimprospatate",
"locatie": [
    "id_alerta": 43,
    "latitudine": "37.41593630609526",
    "longitudine": "-122.09065474569798",
    "tip_problema": "Situa\u021bie 4",
    "data_ora": "2020-01-14 15:44:37",
    "ora_catalogare": null,
    "stare_problema": "Nevalidat",
    "grad_incredere": 65.75
]

即使在数据库中tip_problema 列存储了Situație 4,当它被发送到应用程序时,它在Situa\u021bie 4 中转换。

要建立连接,我使用RequestHandler

public class RequestHandler 
public String sendPostRequest(String requestURL, HashMap<String, String> postDataParams) 
    URL url;

    StringBuilder sb = new StringBuilder();
    try 
        url = new URL(requestURL);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(15000);
        conn.setConnectTimeout(15000);
        conn.setRequestMethod("POST");
        conn.setDoInput(true);
        conn.setDoOutput(true);

        OutputStream os = conn.getOutputStream();

        BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(os, "UTF-8"));
        writer.write(getPostDataString(postDataParams));

        writer.flush();
        writer.close();
        os.close();
        int responseCode = conn.getResponseCode();

        if (responseCode == HttpsURLConnection.HTTP_OK) 

            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            sb = new StringBuilder();
            String response;

            while ((response = br.readLine()) != null) 
                sb.append(response);
            
        

     catch (Exception e) 
        e.printStackTrace();
    
    return sb.toString();


private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException 
    StringBuilder result = new StringBuilder();
    boolean first = true;
    for (Map.Entry<String, String> entry : params.entrySet()) 
        if (first)
            first = false;
        else
            result.append("&");
        result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
        result.append("=");
        result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
    
    return result.toString();

我在任何地方都设置了UTF-8 collation。任何建议将不胜感激! 更新: 我已在InputStream 上将UTF-8 添加到BufferReader,但响应是相同的。 BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));

更新:重新安装应用程序后,即使响应相同Situa\u021bie 4,应用程序似乎也理解该消息指的是Situație 4,因此它现在可以正常工作。

【问题讨论】:

\u021b 只是一种在 JSON 中编码特殊字符 ț 的方法 - 这本质上没有任何问题。如果它正确处理 JSON,您的 android 应用程序应该能够处理它。您还没有向我们展示您实际上是在哪里创建这个 JSON - 在 PHP 中,您可以使用选项 JSON_UNESCAPED_UNICODEjson_encode 不以这种方式编码 Unicode 字符。但这可能有可能在其他地方破坏事情。 我正在使用echo json_encode($response); 创建JSON 【参考方案1】:

请尝试给 BufferedReader 编码

 BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));

【讨论】:

我已经添加了编码但是响应是一样的 重新安装应用程序后,即使响应相同Situa\u021bie 4,应用程序似乎理解该消息指的是Situație 4,因此它现在可以正常工作。所以我想这个答案解决了这个问题!

以上是关于Android应用程序解码来自PHP MySql数据库的JSON响应,没有特殊字符的主要内容,如果未能解决你的问题,请参考以下文章

使用 PHP 验证来自 Android SafetyNet 的 JWS 响应

PHP/Java for Android 之间的数据编码/解码

通过android使用php更新mysql数据库

来自localstorage的JSON无法在php中解码

将现有 PHP/MYSQL/ 网站转换为原生 IOS/Android 应用程序

Android:如何让我检索到的(来自 mysql)JSON 解析数据添加到 ListView 每分钟刷新一次