Почему создание синтаксически недопустимых QNames разрешено в средах Java-сериализации?

Я сталкивался с множеством ошибок сериализации JAXB, которые вызваны тем, что код создает недопустимые квалифицированные имена в разных местах. Я изучаю API, который я использую, и другие параметры java XML, и одна странная вещь заключается в том, что классы, которые реализуют квалифицированные имена, вообще не выполняют никакой проверки ввода.

Это действительно проблематично, потому что сложный код генерирует различные объекты JAXB, и только когда вы выясните, что что-то пошло не так, как надо. Стек исключений обычно не сообщает вам, какой элемент / атрибут неправильный, просто что-то не так.

Разве не имело бы больше смысла для этих библиотек в первую очередь усложнять создание несериализуемого контента?

Вот фрагмент кода: почему это работает? Разве это не должно бросить IllegalArgumentException? В других API, которые определяют QName, поведение такое же. Javadocs для этого класса указывают, что если пространство имен равно нулю, вы получите IllegalArgumentException но не иначе.

    QName q = new QName("Namespace URI is supposed to be an anyURI, but clearly !!THIS ISN'T!!", 
                        "Local part is supposed to be an NCName, but clearly !!THIS ISN'T!!",
                        "<><><><>&&& Laughably Invalid Namespace Prefix");
    System.out.println(q);

Ссылки: Соответствующий javadoc для QName, спецификационные ограничения, указывающие, что name - это anyURI, а localpart - это NCName. Другими словами, согласно спецификации, приведенный выше код явно недействителен, независимо от сериализации.

2 ответа

Гипотезы здесь.

Основной пользователь конструктора QName, скорее всего, сам по себе не является универсальным Java-кодом, но является анализатором XML.

Синтаксический анализ XML чувствителен к производительности. Если конструктор вызывается синтаксическим анализатором, теоретически синтаксический анализатор уже подтвердил синтаксис, поэтому повторная его проверка является пустой тратой времени.

Это 95% проблема. Зачем платить цену за 5% пользователей.

Если вам нужен проверяющий конструктор QName, вы можете расширить QName и добавить свой собственный код.

Например:

public class VerifiedQName extends QName {
    public VerifiedQName(String namespaceURI, String localPart) {            
        super(namespaceURI, localPart);
        verfiyNamespaceURI(namespaceURI); // throws IllegalArgumentException
        verifyLocalPart(localPart);  // throws IllegalArgumentException
    }
    ...
}

По крайней мере, класс задокументирован как не проверяющий.

javax.xml.namespace.QName это не класс JAXB, это просто класс, являющийся частью Java SE, который использует JAXB.

Причина не проверять данные

  1. String манипулирование стоит дорого, вы хотите взять на себя осмотр каждый String каждый раз?
  2. Что, если определение действительного локального имени или пространства имен изменится, то вам нужно сообщить QName какую версию определения проверить? Вы не можете использовать новое определение, пока версия в Java SE не будет обновлена ​​для его поддержки?
  3. В крайнем случае вы можете использовать его с данными не XML. Некоторые реализации JAXB (например, MOXy) поддерживают форматы, отличные от XML (например, JSON), имеющие такие классы, как QName терпимость к "недействительным" данным позволяет использовать их не по назначению.

ОБНОВИТЬ

Знаете ли вы, что это причины, или вы спекулируете?

Чистое предположение, но я веду реализацию EclipseLink MOXy JAXB.

Почему проверка String будет дорогой в конструкторе?

Это дороже, чем ничего не делать. Также, даже если это небольшая цена за вызов конструктора, достаточно выполнить операцию, и она может стать дорогой.

Стоит отметить, что другие типы, связанные со спецификацией (например, URL и URI), оба выбрасывают исключения из своих конструкторов для недопустимых форматов.

Как правило, вы не создаете много таких объектов, поэтому помощь пользователя из исключения перевешивает стоимость выполнения проверки.

Кроме того, когда меняется определение QNames?

Конечно, это вряд ли изменится. Однако в наши дни реализации JAXB часто используются для поддержки не только XML. Иметь толерантный QName Реализация удобна, когда вы читаете / записываете данные из другого формата, такого как JSON.

Другие вопросы по тегам