我收到了一个XML文件,其中包含使用Jackson和Woodstox读取、编辑和编写该文件的说明(根据文档中的建议)。在大多数情况下,这并不是太难;他们都非常擅长它所做的事情。不过,在这一点上,我遇到了一个问题:
我的XML对象本身确实包含XML对象。例如:
<XMLObject>
<OuterObject attributeOne="1" attributeTwo="2" attributeThree=">">
<InnerObject><NestedObject>Blah</NestedObject></InnerObject>
</OuterObject>
<OuterObject attributeOne="11" attributeTwo="22" attributeThree="<">
<InnerObject><NestedObject>Blah</NestedObject></InnerObject>
</OuterObject>
<OuterObject attributeOne="111" attributeTwo="222" attributeThree="3" />
<XMLObject>当我将XML文件读入Jackson注释的Java对象时,Woodstox将<和>的所有实例分别转换为<和>。当我将对象作为XML文件写回时,<变为<,但>保持为>
<XMLObject>
<OuterObject attributeOne="1" attributeTwo="2" attributeThree=">">
<InnerObject><NestedObject>Blah</NestedObject></InnerObject>
</OuterObject>
<OuterObject attributeOne="11" attributeTwo="22" attributeThree="<">
<InnerObject><NestedObject>Blah</NestedObject></InnerObject>
</OuterObject>
<OuterObject attributeOne="111" attributeTwo="222" attributeThree="3" />
<XMLObject>我尝试读取文件的方法的最简单版本如下所示:
@RequestMapping("readXML")
public @ResponseBody CustomXMLObject readXML() throws Exception {
File inputFile = new File(FILE_PATH);
XmlMapper mapper = new XmlMapper();
CustomXMLObject value = mapper.readValue(inputFile, CustomXMLObject .class);
return value;
}对于我上面给出的例子,我的Jackson注释的Java对象看起来像这样:
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CustomXMLObject {
@JacksonXmlProperty(isAttribute=true)
private long attributeOne;
@JacksonXmlProperty(isAttribute=true)
private String attributeTwo;
@JacksonXmlProperty(isAttribute=true)
private String attributeThree;
@JacksonXmlProperty(localName = "InnerObject")
private String innerObject;
public long getAttributeOne() {
return attributeOne;
}
public void setAttributeOne(long attributeOne) {
this.attributeOne = attributeOne;
}
public String getAttributeTwo() {
return attributeTwo;
}
public void setAttributeTwo(String attributeTwo) {
this.attributeTwo = attributeTwo;
}
public String getAttributeThree() {
return attributeThree;
}
public void setAttributeThree(String attributeThree) {
this.attributeThree = attributeThree;
}
public String getInnerObject() {
return innerObject;
}
public void setInnerObject(String innerObject) {
this.innerObject = innerObject;
}
}最后,我的依赖关系如下所示:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>woodstox-core-asl</artifactId>
<version>4.4.1</version>
</dependency>这似乎是由于杰克逊使用伍德斯托克斯的BufferingXmlWriter造成的。这个特定的编写器将拦截这些字符并对它们进行编码,似乎没有任何方法可以绕过这一决定:
private final void writeAttrValue(String value, int len) throws IOException {
int inPtr = 0;
char qchar = this.mEncQuoteChar;
int highChar = this.mEncHighChar;
while(true) {
String ent = null;
while(true) {
if(inPtr >= len) {
return;
}
char c = value.charAt(inPtr++);
if(c <= 60) {
if(c < 32) {
if(c == 13) {
if(this.mEscapeCR) {
break;
}
} else {
if(c == 10 || c == 9 || this.mXml11 && c != 0) {
break;
}
c = this.handleInvalidChar(c);
}
} else {
if(c == qchar) {
ent = this.mEncQuoteEntity;
break;
}
if(c == 60) {
ent = "<";
break;
}
if(c == 38) {
ent = "&";
break;
}
}
} else if(c >= highChar) {
break;
}
if(this.mOutputPtr >= this.mOutputBufLen) {
this.flushBuffer();
}
this.mOutputBuffer[this.mOutputPtr++] = c;
}
if(ent != null) {
this.writeRaw(ent);
} else {
this.writeAsEntity(value.charAt(inPtr - 1));
}
}
}最后总结一下这个问题,我得到了一个XML文件。该XML文件包含属性和元素,这些属性和元素本身包含已编码的符号(<和>) (<和>),这样就不会破坏XML。当Woodstox读取文件时,它将对字符进行解码,而不是将XML中包含的实际字符串传递给Java对象。在写入时,只有<会被重新编码为<。这似乎是因为杰克逊正在使用Woodstox的BufferingXmlWriter,它似乎无法配置以避免对这些字符进行编码。
因此,我的问题如下:
我是否可以将Jackson对象配置为使用Woodstox XML阅读器,以便在不进行进一步编码的情况下读取和写入XML文件中的字符,或者我是否需要完全根据自己的需要寻找不同的解决方案?
发布于 2016-11-12 00:09:30
您可以将底层XMLOutputFactory2配置为使用CharacterEscapes,它可以指定覆盖默认情况下转义的内容。这会不会:
http://www.cowtowncoder.com/blog/archives/2012/08/entry_476.html
工作?
编辑:对上面的建议表示歉意--这不适用于XML,只适用于JSON。我应该再检查一遍的。虽然有一个工作项可以让它也与XML一起工作,但这还不存在(截至2016年11月)。
https://stackoverflow.com/questions/40412978
复制相似问题