即使一切都正确,Jackson Streaming API 仍会抛出“无法写入字段名称,需要值”错误

问题描述

我正在尝试使用 Jackson Streaming API 将 XML 转换为 JSON。输入的 XML 文件可能非常大,因此我使用 SAX PARSER 来解析 XML 并使用 JACKSON STREAMING API 将其转换为 JSON。到目前为止,我使用这个简单的例子只是为了使用 JACKSON 创建基本的 JSON,但它会导致一个错误

com.fasterxml.jackson.core.JsonGenerationException: Can not write a field name,expecting a value

我正在尝试调用另一种方法,该方法将在导致错误的特定标签末尾写入我的 JSON。如果我不调用一个方法而是在 endElementSAX PARSER 方法中写入,那么我不会收到我觉得有点奇怪的错误

以下是我的代码

public class JsonSaxHandler1 extends DefaultHandler {
    private JsonFactory jsonfactory = new JsonFactory();
    private StringWriter jsonObjectWriter = new StringWriter();
    private JsonGenerator jsonGenerator;
    private static JsonSaxHandler1 saxHandlerObj = null;

    public JsonSaxHandler1() throws IOException {
        jsonGenerator = jsonfactory.createGenerator(jsonObjectWriter);
    }

    @Override
    public void startDocument() {
        try {
            System.out.println("START");
            jsonGenerator.writeStartObject();
            saxHandlerObj = new JsonSaxHandler1();

        } catch (IOException e) {
            e.printstacktrace();
        }
    }

    @Override
    public void startElement(String uri,String localName,String qName,Attributes attribs) throws SAXException {

    }

    @Override
    public void characters(char[] ch,int start,int length) throws SAXException {

    }

    @Override
    public void endElement(String uri,String qName) throws SAXException {
        if (qName.equalsIgnoreCase("school")) {
            saxHandlerObj.createJSON();
        }
    }

    public void createJSON() {
        try {
            jsonGenerator.writeStringField("country","India");
        } catch (IOException e) {
            e.printstacktrace();
        }
    }

    @Override
    public void endDocument() {

        try {
            jsonGenerator.writeEndobject();
            jsonGenerator.flush();
            jsonGenerator.close();
            System.out.println(jsonObjectWriter.toString());
        } catch (IOException e) {
            e.printstacktrace();
        }
    }
}

基本上 startDocument 在 XML 文档的开头被调用startElement 在每个元素标记的开头调用,例如,。 endElement 在每个元素,的末尾调用endDocument 在完整的 XML 文档末尾被调用

我正在尝试在 JSON Object 中创建初始 startDocument 并在 endDocument 中结束它,但在 writeJSON 方法中写入值。

如果我省略 writeJSON 方法并尝试直接在 endDocument 中写入,那么everythign 将完美运行并且能够获得 JSON

@Override
public void endElement(String uri,String qName) throws SAXException {
    if (qName.equalsIgnoreCase("school")) {
        try {
            // saxHandlerObj.createJSON();
            jsonGenerator.writeStringField("country","India");
        } catch (IOException e) {
            // Todo Auto-generated catch block
            e.printstacktrace();
        }
        saxHandlerObj.createJSON();
    }
}

这意味着程序运行的流程是正确的,我正确地创建了所有 JSON Object。只有当我尝试调用不同的方法来编写我的 JSON 内容时,我才会遇到这个问题。我觉得这应该有效,因为调用只在文档末尾发生一次。

以下是我的 XML:(这是示例 XML)

<?xml version="1.0"?>
<school>
    <students>
        <student>
            <name>BATMAN</name>
        </student>
    </students>
</school>

我想在此应用程序中使用 Jackson Streaming APISAX PARSER,因此任何解决此问题的建议都会非常有用。

解决方法

终于找到了问题所在。它实际上与 JACKSON 无关。 我在 saxHandlerObj 中创建了对象 startElement,我不应该这样做。我应该在 Default Constructor 中创建该对象,所以我更改为这样的内容并且它起作用了:

public JsonSaxHandler() throws IOException {
    jsonGenerator = jsonfactory.createGenerator(jsonObjectWriter);
    saxHandlerObj = new JsonSaxHandler();
}

@Override
public void startDocument() {
    try {
        System.out.println("START");
        jsonGenerator.writeStartObject();

    } catch (IOException e) {
        e.printStackTrace();
    }
}