【发布时间】: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