【问题标题】:Spring Boot REST application with Jackson - how to handle arbitrary/unknown xml structures passed in?带有 Jackson 的 Spring Boot REST 应用程序 - 如何处理传入的任意/未知 xml 结构?
【发布时间】:2015-08-28 18:48:42
【问题描述】:

我正在使用 Spring Boot REST 应用程序。我们正在使用 jackson 来处理 XML 的反序列化以及在请求正文中传递的 JSON。预期请求正文的示例如下所示:

<formInput><formNum>999999</formNum><documentData>Completely unknown data structure here!</documentData></formInput>

在 documentData 元素中,我们将拥有一个在服务器端完全任意/未知的结构。我们不关心结构,因为我们只想将嵌套在 documentData 中的 xml 传递给另一个服务。

我们试图将请求正文映射到的 POJO 如下所示:

@JsonDeserialize(using=FormInputJsonDeserializer.class)
public class FormInput {

    private String formNum
    private String documentData

    public String getFormNum() {
        return formNum
    }

    public void setFormNum(String formNum) {
        this.formNum = formNum
    }

    public String getDocumentData() {
        return documentData;
    }

    public void setDocumentData(String documentData) {
        this.documentData = documentData;
    }

}

我们正在尝试编写的自定义 JsonDeserializer:

public class FormInputJsonDeserializer extends JsonDeserializer<FormInput> {
    @Override
    public FormInput deserialize(JsonParser parser, DeserializationContext context)
            throws IOException, JsonProcessingException {       

        FormInput formInput = new FormInput();

        String fieldName
        JsonToken currentToken
        while (parser.nextToken() != null) {
            currentToken = parser.getCurrentToken()
            if (currentToken.equals(JsonToken.END_OBJECT)) {
                continue
            }

            fieldName = parser.getCurrentName()

            // formNum handling not written yet

            if ("documentData".equalsIgnoreCase(fieldName)) {
                if (parser.getCurrentToken().equals(JsonToken.START_OBJECT)) {
                    // we are at the start of documentData, and we need to capture the
                    // entire documentData node as a String since we don't know
                    // its structure
                    JsonFactory jfactory = new JsonFactory()
                    StringWriter jsonStringWriter = new StringWriter()
                    JsonGenerator jGen = jfactory.createGenerator(jsonStringWriter)
                    jGen.copyCurrentStructure(parser) // points to END_OBJECT after copy
                    jGen.close()
                    String documentDataJsonStr = jsonStringWriter.getBuffer().toString()
                    println("documentDataJsonStr: " + documentDataJsonStr)
                }
            }
        }

        // rest of code omitted
    }

}

正如我所说,如果请求正文是 xml,理想情况下,我希望将其保持为 xml 格式并将其分配给 documentData String 属性。但是,我按照 StackOverflow 上的其他一些示例提出了上述自定义反序列化代码。此解析代码最终将 documentData 转换为 JSON 格式的字符串。因为我不知道如何传递原始 XML 并将其映射到 String 属性,所以我想我可以将 JSON 格式的字符串转换回 XML 格式的字符串。当我们传入这样的 XML 结构时会出现问题:

<formInput><formNum>9322</formNum><documentData><repeatLevel><subForm1><GROSS_DISTR>    13,004.31</GROSS_DISTR><GROSS_DISTR>    13,004.31</GROSS_DISTR><GROSS_DISTR>    13,004.31</GROSS_DISTR></subForm1></repeatLevel><repeatLevel><subForm1><GROSS_DISTR>    38,681.37</GROSS_DISTR><GROSS_DISTR>    38,681.37</GROSS_DISTR><GROSS_DISTR>    38,681.37</GROSS_DISTR></subForm1></repeatLevel></documentData></formInput>    

在deserialize方法中解析documentData后,println语句显示解析后的JSON String为:

{"repeatLevel":{"subForm1":{"GROSS_DISTR":"    13,004.31","GROSS_DISTR":"    13,004.31","GROSS_DISTR":"    13,004.31"}},"repeatLevel":{"subForm1":{"GROSS_DISTR":"    38,681.37","GROSS_DISTR":"    38,681.37","GROSS_DISTR":"    38,681.37"}}}

由于重复的键,这实际上不是严格有效的 JSON。我本来希望这些会被转换为 JSON 数组,但事实并非如此。因此,我无法转身使用 JSON.org 库(JsonObject 和 XML)之类的东西将 JSON 字符串转换回 XML 格式(出现“重复键”错误的异常)。

有人对我们的情况有什么建议或策略吗?

【问题讨论】:

  • 抱歉,忘了说这些其实是 Groovy 类,所以很多地方都省略了分号。

标签: java spring rest jackson spring-boot


【解决方案1】:

您可以尝试使用 JSONObject,添加 @JsonIgnoreProperties("documentData") 标签并使用 substring() 从原始数据中单独提取 documentData

【讨论】:

    猜你喜欢
    • 2019-01-15
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    • 2018-02-28
    • 2014-10-25
    • 2019-01-13
    • 1970-01-01
    • 2017-10-21
    相关资源
    最近更新 更多