我正在处理一个执行大量XML操作的应用程序,所以我试图让JAXB在其中工作。我有一个CustomEscapeHandler的以下类: import com.sun.xml.bind.marshaller.CharacterEscapeHandler;
import java.io.IOException;
import java.io.Writer;
public class CustomEscapeHandler implements CharacterEscapeHandler {
private static final CharacterEscapeHandler theInstance = new CustomEscapeHandler();
private CustomEscapeHandler() {
}
public static CharacterEscapeHandler getInstance() {
return theInstance;
}
public void escape(char[] ch, int start, int length, boolean isAttVal, Writer out) throws IOException {
int limit = start + length;
for(int i = start; i < limit; ++i) {
char c = ch[i];
if (c == 38 || c == 39 || c == 60 || c == 62 || c == 13 || c == 34 && isAttVal) {
if (i != start) {
out.write(ch, start, i - start);
}
start = i + 1;
switch(ch[i]) {
case '\"':
out.write(""");
break;
case '&':
out.write("&");
break;
case '<':
out.write("<");
break;
case '>':
out.write(">");
break;
case '\'':
out.write("'");
break;
}
}
}
if (start != limit) {
out.write(ch, start, limit - start);
}
}
}
如果我使用
jaxbMarshaller.setProperty("com.sun.xml.internal.bind.characterEscapeHandler", CustomEscapeHandler.getInstance());
我得到了
javax.xml.bind.PropertyException: property "com.sun.xml.internal.bind.characterEscapeHandler" must be an instance of type com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler, not my.package.CustomEscapeHandler
所以,如果我将其改为
jaxbMarshaller.setProperty("com.sun.xml.bind.marshaller.CharacterEscapeHandler", CustomEscapeHandler.getInstance());
我得到了
javax.xml.bind.PropertyException: name: com.sun.xml.bind.marshaller.CharacterEscapeHandler value: my.package.CustomEscapeHandler@e2b4f3
at javax.xml.bind.helpers.AbstractMarshallerImpl.setProperty(AbstractMarshallerImpl.java:358)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.setProperty(MarshallerImpl.java:527)
at my.package.util.XmlUtils.convert(XmlUtils.java:39)
at my.package.util.XmlUtils.convertFormToXml(XmlUtils.java:28)
at my.package.FormsMain.saveXML(FormsMain.java:362)
at my.package.FormsMain.saveForms(FormsMain.java:499)
at my.package.FormsMain.lambda$createWindow$3(FormsMain.java:231)
查看堆栈跟踪,它试图在内部包中使用marshaller,它也查看反编译代码,期望转义处理程序是内部包中CharacterEscapeHandler的实现。 / p>
如何让JAXB不使用内部包实现?
一个月后,仍然无法找到解决方案。我在网上看到的每个例子都扩展了CharacterEscapeHandler的内部版本。
答案 0 :(得分:0)
这里的问题是使用内部“ com.sun.xml.internal”包中的CharacterEscapeHandler。即使您的代码可以工作,这也不是一个好主意。而是使用com.sun.xml.bind.marshaller.CharacterEscapeHandler中的类似类,它将为您解决问题。
答案 1 :(得分:0)
您应该能够通过设置启动属性来控制使用的编组器:
javax.xml.bind.context.factory=com.sun.xml.bind.v2.ContextFactory
这会将它设置为 JAXB 参考实现而不是内部上下文工厂,相应地,您获得的编组器将是 com.sun.xml.bind.v2.runtime.MarshallerImpl 类型,而不是内部的。
如果您查看 JAXBContext 类的内部,在 newInstance 方法中,您将看到它调用了一个类 ContextFinder.find,并且该方法读取 javax.xml.bind.context.factory 属性以了解 JAXB要使用的上下文工厂。