2

我正在尝试使用 GSON 库开发一个 Java 应用程序来解析 JSON(来自 PHP 文件(UTF-8 编码)-> json_encode)

我的 php 源代码:

<?php
$base = mysql_connect ('****', '*****', '*****');  
mysql_select_db ('*****', $base) ; 
$req = mysql_query("SELECT ***, ****, ***, ****, **** from *****");

function jsonRemoveUnicodeSequences($struct) {
   return preg_replace("/\\\\u([a-f0-9]{4})/e", "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))",               json_encode($struct));
}

while ($row = mysql_fetch_array($req)) {
    $output[] = $row;
}

print(jsonRemoveUnicodeSequences($output));    
mysql_free_result ($req);    
?>

JSON 字符串在我的网络浏览器中正确显示并带有重音符号。

我的 Java 源代码:

        BufferedReader reader = null;

        try {
            URL url = new URL("**************");
            URLConnection urlConnection = url.openConnection(); 

            reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));

            StringBuilder sb = new StringBuilder();            
            String line = null;  

            while ((line = reader.readLine()) != null) {
                sb.append(line);
                System.out.println("JSON data issu du PHP : "+ line + "\n");
                Gson gson = new Gson();

                Type type = new TypeToken<List<AlertTable>>(){}.getType();
                ArrayList<AlertTable> bddListJson = gson.fromJson(line, type);              
                bddList = (ArrayList<AlertTable>) bddListJson.clone();                   
            }
        } catch (IOException e) {
            //
        } finally {
            if (reader != null) {
                //
            }
        }   

        System.out.println(bddList.get(1).getTypeAlert());
        System.out.println(bddList.get(1).getLigne());
        System.out.println(bddList.get(1).getSens());
        System.out.println(bddList.get(1).getStation());
        System.out.println(bddList.get(1).getTimeAlert());

在控制台中,带有重音的字符被替换为“?”。

任何的想法 ?

4

2 回答 2

1

首先,请注意您的代码在某些系统上可能会失败,因为 MySQL 使用连接字符集在客户端和服务器之间移动文本。您应该发出一个原始查询,例如SET NAMES <charset>设置脚本中可用输入数据的编码。

现在,假设没有转码问题(因为您的列只存储 ASCII 字符并且所有涉及的字符集都是 ASCII 兼容的),我编写了以下代码以\u0000用 UTF8 编码的字符串替换转义序列:

<?php

while ($row = mysql_fetch_array($req)) {
  $out[] = preg_replace_callback("/\\\\u([a-f0-9]{4})/i", "unescape", $row);
}

// On PHP 5.4+ use json_encode($out, JSON_UNESCAPED_UNICODE)
echo json_encode($out);

/* Accept the matcher array
 * return the UTF-8 encoded string
 */
function unescape($match) {
  return call_user_func_array('pack', get_pack_args(hexdec($match[1])));
}

function get_pack_args($cp) {
  if ($cp < 0x80) return array('C1', $cp);

  if ($cp < 0x0800) {
    $length = 2;
  } else if ($cp < 0x010000) {
    $length = 3;
  } else {
    $length = 4;
  }

  $args[0] = "C{$length}";

  // lead byte
  $args[1] = (0xFE << (7 - $length)) | ($cp >> (6 * ($length - 1)));

  // continuation bytes
  for ($l = 0; $l < ($length - 1); $l++) {
    $args[$length - $l] = 0x80 | (($cp >> (6 * $l)) & 0x3F);
  }

  // stupid PHP...
  ksort($args);
  return $args;
}

您应该深入测试代码,但这是一个很好的起点。为了在浏览器中显示,您应该使用 HTTP 标头指定编码:

header('Content-Type: application/json; charset=utf8');

请注意,json_encode()默认情况下会转义 unicode 序列。这是低效的,因此您可能想要使用该JSON_UNESCAPED_UNICODE标志,或者选择另一个 JSON 库进行编码。

此时服务器部分应该没问题了,你可以用你的浏览器测试一下。如果它可以工作,但 Java 程序仍然无法在控制台上显示正确的字符,则可能是控制台本身有问题,甚至是控制台应用程序使用的字体有问题。如果没有实际数据,则无法分辨,但请按照我的建议将 JSON 打印到 UTF8 编码的文本文件中。然后用文本编辑器打开它(如果需要,指定 UTF-8)并告诉你所看到的。

最后,请注意mysql不鼓励使用 PHP 扩展。使用mysqliPDO代替。

于 2013-02-11T01:06:56.563 回答
0

如果您正确设置了 json_encode 的参数,例如

 json_encode($WhoRank,JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE);

编码值和传输数据没有问题,但如果不能再次工作,您可以使用urlencode对 UTF-8 值进行编码并在 Java 上对其进行解码

像这样

urlencode('aیgfسبd');

输出

a%DB%8Cgf%D8%B3%D8%A8d

有了这个输出,你的 json 值没有问题。

于 2013-02-10T19:23:38.947 回答