Десериализация XML с XMLScanner, что приводит к увеличению выходной строки
Процесс обновления нашего продукта включает в себя экспорт старой схемы БД в файлы (сериализация JAXB), а затем импорт в новую схему (StAX + JAXB). Иногда происходит сбой обновления из-за ошибок вставки, вызванных значениями, превышающими их максимальный размер, несмотря на то, что они были ранее экспортированы из той же таблицы БД.
Это произошло при десериализации xml (в данном случае с Jaxb, но он не связан только с Jaxb), и один из атрибутов имеет значение с последовательностью старших суррогатных символов UTF-8, в синтаксическом анализаторе SAX есть ошибка, приводящая к увеличению выходной строки:
3 символа -> (1+2+3=) 6 символов.
6 символов -> (1+2+3+4+5+6=) 21 символ.
(Арифметическая прогрессия исходных символов)
Код взят из класса кода Java 1.7_45 com.sun.org.apache.xerces.internal.impl.XMLScanner: 976 - 981:
else if (c != -1 && XMLChar.isHighSurrogate(c)) {
if (scanSurrogates(fStringBuffer3)) {
stringBuffer.append(fStringBuffer3);
if (entityDepth == fEntityDepth && fNeedNonNormalizedValue){
fStringBuffer2.append(fStringBuffer3);
}
БуферfStringBuffer3 не очищается между циклами.
Аналогичный код существует (то же имя метода) в строках com.sun.org.apache.xerces.internal.impl.XML11DocumentScannerImpl: 369 - 375. Но на этот раз буфер очищался во время циклов:
else if (c != -1 && XMLChar.isHighSurrogate(c)) {
fStringBuffer3.clear();
if (scanSurrogates(fStringBuffer3)) {
fStringBuffer.append(fStringBuffer3);
if (entityDepth == fEntityDepth) {
fStringBuffer2.append(fStringBuffer3);
}
}
Я проверил базу данных ошибок Java, эта ошибка там не упоминается. Поэтому я ищу решение этой проблемы, замена парсера JAXB на парсер Woodstox решает проблему, к сожалению, для нас это слишком рискованно.
Общий шаблон моего кода (часть метода, который возвращает объект, который был десериализован из файла):
XMLInputFactory xmlif = XMLInputFactory.newInstance();
XMLStreamReader xmlStreamReader = xmlif.createXMLStreamReader(new FileReader(file));
try {
while(xmlStreamReader.hasNext()){
boolean skipNext = xmlStreamReader.getEventType() == XMLStreamConstants.START_DOCUMENT;
xmlStreamReader.next();
// If its any other element we are unmarshalling it with JAXB
if((xmlStreamReader.getEventType()== XMLStreamConstants.START_ELEMENT) && !skipNext){
nextElement = innerDeserializer.deserialize();
}
}
}catch (Exception e) {}
Кто-нибудь решил с этой проблемой? Есть ли способ заставить мой код использовать второй кусок кода без использования XML версии 1.1?
1 ответ
Если ошибка в синтаксическом анализаторе SAX, который по умолчанию эталонная реализация JAXB использует для обработки XML. Вы могли бы создать StAX XMLStreamReader
на входе и JAXB разобрать это.