替换&与&使用Jackson ObjectMapper

时间:2018-01-30 14:46:10

标签: java json xml jackson juel

在我正在工作的应用程序中,我们需要将一个巨大的json转换为更大的XML。两个元素的结构非常不同,因此我们决定创建一个与XSD匹配的XML文件,并使用统一表达式语言填充字段。例如:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Objects xmlns="..">
  <Object>
    <Field>${json.field}</Field>
  <Object>
<Objects>

使用JUEL

替换${json.field}

在运行JUEL流程之后,我们将xml字符串解组到对象中,然后继续该过程。 unmarshal代码是这样的:

  private XmlObjects unmarshal(StringReader xmlString) {
    try {
      Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
      return (XmlObjects) unmarshaller.unmarshal(xmlString);
    } catch (JAXBException e) {
      throw new RuntimeException(e);
    }
  }

我们面临的问题是json.field可能包含XML中不允许的字符,例如&amp;或&lt;,&gt;。

一个简单的解决方法是更换所有&amp;由&amp;在上述方法中,但这并不能解决&lt;或者&gt;我不能在那一点上取而代之。

我想做的是在json映射到POJO时使用Jackson进行替换,但我找不到办法。到目前为止,我已尝试创建自定义CharacterEscapes类并将其设置为ObjectMapper但不起作用。

所以,这是总结所有内容的测试:

  @Test
  public void test() throws IOException {
    ObjectMapper objectMapper = Jackson.newObjectMapper();
    objectMapper.getFactory().setCharacterEscapes(new XMLCharacterEscapes());

    String json = "{\"variable\":\"a string with &\"}";
    FooJson fooJson = objectMapper.readValue(json, FooJson.class);
    assertEquals("a string with &amp;", fooJson.getVariable());
  }

这是XMLCharacterEscapes类:

public class XMLCharacterEscapes extends CharacterEscapes {

  private final int[] asciiEscapes;

  public XMLCharacterEscapes() {
    int[] esc = CharacterEscapes.standardAsciiEscapesForJSON();
    esc['&'] = CharacterEscapes.ESCAPE_CUSTOM;
    asciiEscapes = esc;
  }

  @Override
  public int[] getEscapeCodesForAscii() {
    return asciiEscapes;
  }

  @Override
  public SerializableString getEscapeSequence(int i) {
    return new SerializedString("&amp;");
  }
}

2 个答案:

答案 0 :(得分:0)

如果我可以提出替代方案,您是否可以让您的unmarshaller在读取XML时将JUEL应用于元素值?或者,您可以在解组之后遍历XML对象图并将JUEL应用于元素值吗?

编辑:似乎问题只是您应用替换的顺序。一旦你有了一个XML文档,你应该能够设置你喜欢的任何值,它将负责正确的转义。

答案 1 :(得分:0)

将您的字段包含在CDATA部分

<Field><![CDATA[${json.field}]]></Field>