杰克逊JSON解析器无效的UTF-8起始字节

30

我正在尝试解析以下 JSON,但始终遇到 JsonParseException 错误:

{
   "episodes":{
      "description":"Episode 3 – Oprah's Surprise Patrol from 1\/20\/04\nTake a trip down memory lane and hear all your favorite episodes of The Oprah Winfrey Show from the last 25 seasons -- everyday on your radio!"
   }
}

同样在这个JSON上失败了

{
   "episodes":{
      "description":"After 20 years in sports talk…he’s still the top dog!  Catch Christopher “Mad Dog” Russo weekday afternoons on Mad Dog Radio as he tells it like it is…Give the Doggie a call at 888-623-3646."
   }
}

异常:

org.codehaus.jackson.JsonParseException: Invalid UTF-8 start byte 0x96
 at [Source: C:\Json Test Files\episodes.txt; line: 3, column: 33]
    at org.codehaus.jackson.JsonParser._constructError(JsonParser.java:1291)
    at org.codehaus.jackson.impl.JsonParserMinimalBase._reportError(JsonParserMinimalBase.java:385)
    at org.codehaus.jackson.impl.Utf8StreamParser._reportInvalidInitial(Utf8StreamParser.java:2236)
    at org.codehaus.jackson.impl.Utf8StreamParser._reportInvalidChar(Utf8StreamParser.java:2230)
    at org.codehaus.jackson.impl.Utf8StreamParser._finishString2(Utf8StreamParser.java:1467)
    at org.codehaus.jackson.impl.Utf8StreamParser._finishString(Utf8StreamParser.java:1394)
    at org.codehaus.jackson.impl.Utf8StreamParser.getText(Utf8StreamParser.java:113)
    at com.niveus.jackson.Main.parseEpisodes(Main.java:37)
    at com.niveus.jackson.Main.main(Main.java:13)

代码:

    public static void main(String [] args) {
        parseEpisodes("C:\\Json Test Files\\episodes.txt");
    }
    public static void parseEpisodes(String filename) {
        JsonFactory factory = new JsonFactory();
        JsonParser parser = null;
        String nameField = null;
        
        try {
            parser = factory.createJsonParser(new File(filename));
            
            parser.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
            parser.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);
            
            JsonToken token = parser.nextToken();
            nameField = parser.getText();
            String desc = null;
            
            while (token != JsonToken.END_OBJECT) {
                if (nameField.equals("episodes")) {
                    while (token != JsonToken.END_OBJECT) {
                        if (nameField.equals("description")) {
                            parser.nextToken();
                            desc = parser.getText();
                        }
                        
                        token = parser.nextToken();
                        nameField = parser.getText();
                    }
                }
                
                token = parser.nextToken();
                nameField = parser.getText();
            }
            
            System.out.println(desc);
        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
4个回答

29

第33列的字符是,这意味着文件实际上是使用Windows-1252进行物理编码所导致的字节0x96。你需要将文件保存为UTF-8,因为windows-1252不是JSON的有效编码。如何操作取决于你正在使用的文本编辑器。

请查看JSON RFC

  1. 编码

    JSON文本必须使用Unicode编码,默认编码为UTF-8。


1
我下载一个JSON字符串响应作为UTF-8,并将内容写入一个.txt文件(UTF-8)到我的Android SD存储,然后将该文件复制到我的台式电脑。 - Android Noob
我也在Windows上使用记事本打开文件。 - Android Noob
1
在某个过程中,你所认为的UTF-8实际上是Windows-1252。我猜测原始下载文件标签有误。顺便说一下,0x96是“en-dash”字符,这是MS Word用作连字符的字符。在第二个例子中,罪魁祸首是省略号字符,也是MS Word的特殊习惯。 - Jim Garrison
1
@AndroidNoob,字节0x96在UTF-8编码的文件中永远不会单独出现,因为它是一个连续字节。在记事本中打开该文件,按保存,然后从编码菜单中选择“UTF-8”。 - Esailija

2

我也遇到过类似的问题。打开你的json文件,使用Notepad ++,然后在编码下拉菜单中选择UTF-8,将文本保存到其他文件中。这样做可以解决问题。


0

我知道这个问题很老了,但我想分享一些对我有用的东西。可以通过以下方式忽略字符。

  1. 定义一个字符集解码器

    StandardCharsets.UTF_8.newDecoder().onMalformedInput(CodingErrorAction.IGNORE);

  2. 使用它来读取InputStream

    InputStreamReader stream = new InputStreamReader(resource.getInputStream(), CHARSET_DECODER)

  3. 使用Jackson CSV映射器读取内容

    new CsvMapper().readerFor(Map.class).readValues(stream);

关键元素在于带有IGNORE选项的字符集解码器中的错误输入。


0

这里提到的所有方法我都尝试过,但没有解决我的问题,所以我手动输入了有效载荷来解决它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接