Мне предоставлен XML-файл с инструкцией для чтения, редактирования и записи с использованием Jackson and Woodstox (согласно рекомендации в документации). По большей части это было не слишком сложно; Они оба довольно хороши в том, что он делает. На данный момент я столкнулся с проблемой:Толкование символов в кодировке XML в JavaScript 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 в мой Джексон-аннотированный объекта 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;
}
И мой объект Jacob-annotated 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 Woodstox». Этот конкретный автор будет перехватывать эти символы и кодировать их, и не кажется, каким-либо образом обойти это решение:
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 читает файл, вместо того чтобы передать мой объект Java фактическую строку, содержащуюся в XML, он декодирует символ. При записи только <
перекодируется как <
. Кажется, это происходит потому, что Джексон использует BufferingXmlWriter от Woodstox, который, похоже, не настраивается, чтобы избежать кодирования этих символов.
В результате, мой вопрос заключается в следующем:
Могу ли я настроить объект Джексона использовать для чтения Woodstox XML, который позволит моим читать и писать символы в моем файле XML без дальнейшего кодирования, или сделать Мне нужно искать другое решение для моих нужд?
К сожалению, нет. Согласно https://github.com/FasterXML/jackson-dataformat-xml/issues/75 текущая сборка не поддерживает функцию Escape Escape. Я попытался реализовать это независимо от того, что нет. –
@MatthewSnook да и нет: текущая версия не поддерживает удобный доступ; но ничего не мешает вам предоставить специально сконфигурированный 'XMLOutputFactory2' для' XmlMapper' (или, может быть, через 'XmlFactory', я забыл детали). Так что есть немного больше проводки для использования, но это должно быть выполнимо. – StaxMan
Хм .... ну, тогда мне нужно немного больше рекомендаций. Просто после того, как процесс из этого сообщения в блоге, похоже, ничего не делает для чтения/записи данных. –