Съвети и трикове за уеб услуги: Избягвайте анонимни типове

Какво е анонимен тип

Анонимният XML тип е тип, вграден в елемента xsd: element и следователно няма име. Пример е показан в Листинг 1.

Листинг 1. Анонимен тип човек

Комплексният тип на елемент с име сам няма име, така че е анонимен. Този анонимен тип може да бъде преобразуван в именен тип, като направите следните прости стъпки:

  • Преместете дефиницията на complexType в глобален обхват.
  • Дайте на complexType име атрибут.
  • Посочете глобален елемент с атрибут type, който се позовава на complexType.

В листинг 2 изпълнихме тези стъпки и преобразувахме анонимния тип в листинг 1 в именен тип.

Листинг 2. Имената тип Person

Схемите в списъци 1 и 2 са логически идентични. Всяко от тях може да се използва за проверка на XML екземпляра, показан в Листинг 3.

Листинг 3. Именият тип Person

Защо анонимните типове са лоши

За останалата част от тази статия ще използваме схемите, показани в списъци 4 и 5. Списък 4 няма нито един именен тип. Всички видове са анонимни. За сравнение, Листинг 5 показва еквивалентната схема с именувани типове. Когато създавахме Листинг 5, ние приложихме горните стъпки към Листинг 4.

Листинг 4. Елементът акаунт, дефиниран с анонимни типове
Листинг 5. Елементът на акаунта, дефиниран с имена на типове

Защо не харесваме анонимните типове в Листинг 4?

  • Без повторна употреба.
  • Анонимните типове често трябва да бъдат именувани така или иначе.
  • Листинг 4 не е толкова елегантен като Листинг 5.

В останалата част на тази статия ще разгледаме по-отблизо всеки от тези аспекти.

Без повторна употреба

Например двойката firstName/lastName се дублира в Листинг 4 - едната в елемента външно лице, а другата в елемента вътрешно лице. За да се даде възможност за повторно използване, тези два типа трябва да бъдат поставени в техния собствен именуван тип. Без такъв именуван тип елементите просто биха били копирани от един раздел на диаграмата в друг.

Забележете, че в Листинг 5 вече имаме такъв именуван тип, Person. Листинг 5 е наименованият еквивалент на Листинг 4; не сме правили промени, които биха повлияли на структурата на XML копията. Но сега, когато имаме имен тип Person, можем да подобрим схемата в Листинг 5, като използваме повторно типа Person вътре в AccountOwner.

Анонимните типове често трябва да бъдат именувани така или иначе

Дори ако не се интересувате от повторна употреба, анонимните типове все още са потенциално опасни. Нека да разгледаме използването на XML схема. Например, има доста голяма вероятност XML схема да се свърже с език за програмиране в дефиниция на уеб услуга. Ако е така, типовете вече не могат да бъдат анонимни в рамките на даден език. Те трябва да бъдат именувани по някакъв начин и това име трябва да бъде наследено от околната схема. Каквито и правила да се използват за това, възможен е сценарий, който да нарушава тези правила.

Например правилата за картографиране на Java XML схеми, дефинирани в спецификацията JAXB, са нарушени в схемата, дефинирана в Листинг 4. JAXB указва, че анонимният клас тип приема име, което наследява от съдържащия го елемент. Освен това вградените анонимни сложни типове в XML стават вътрешни класове в Java. Според JAXB, XML схемата, показана в Листинг 4, ще се преобразува в следните Java класове:

  • Сметка
  • Акаунт, Личност
  • Account.Person.OtherNamesOnAccount
  • Account.Person.OtherNamesOnAccount.Person

Java не позволява вложените класове да имат същите имена като съдържащите ги класове. В този случай ще се покаже следната грешка при компилацията: "Вложеният тип Person не може да скрие заграждащ тип".

Решаваме проблема, като назоваваме всички типове, както е в Листинг 5. Можете да видите, че използвахме основно правилото за наследяване на име JAXB - наследяването на името на тип Java от името на заобикалящия го елемент. Но не направихме това за всички типове, защото в противен случай щяхме да имаме два типа Личност. Затова преименувахме типа на първия елемент Person на AccountOwner.

Файл за свързване на JAXB

Въпреки че нашето решение ни харесва, то изисква промяна в XML схемата. В случаите, когато схемата не може да бъде променена, JAXB предоставя друго решение. JAXB позволява на потребителя да напише обвързващ файл, който казва на JAXB двигателя как да изобрази XML в Java. Авторите на спецификацията JAXB са знаели, че дадено картографиране не винаги ще работи, така че те предоставят този механизъм за отклонение. Листинг 6 показва свързващ файл, който казва на генератора JAXB да замени класа, генериран от анонимния комплексType на елемента от първо лице с клас, наречен AccountOwner.

Листинг 6. JAXB свързващ файл, необходим за отстраняване на проблема в Листинг 4

Вътрешният елемент на jaxb: bindings съдържа атрибут schemaLocation, който показва на двигателя схемата, която този свързващ файл засяга; той също съдържа атрибут на възел, чиято стойност е израз XPath за елемента, за който искате да приложите специално обвързване. Елементът jaxb: class указва, че класът JAXB, генериран от този XPath елемент, ще бъде наречен AccountOwner. Вижте Ресурси за връзки към повече информация за файла за свързване на JAXB.

Технологията JAXB е достатъчно здрава, за да позволи анонимните типове да бъдат именувани чрез свързващ файл. Но това усложнява процеса на създаване на услуга. Освен това не можете да сте сигурни, че всички съпоставяния на езици ще ви осигурят еднакво ниво на функционалност. Следователно, ако е възможно, е по-добре да промените схемите.

Липса на елегантност

Заключение

Използването на анонимни типове трябва да се избягва поради следните причини:

  • те не могат да се използват многократно;
  • те могат да причинят проблеми, когато картографирането трябва да назове анонимни типове;
  • те не са толкова елегантни като назованите типове.

Можете да избегнете тези проблеми, като конвертирате анонимни типове в именувани. Ако не можете да промените схемата, когато JAXB преобразува XML схеми в Java, можете да създадете свързващ файл за JAXB механизма, който ще отстрани всички възможни проблеми.