DTD и соответствующий XML-документ
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

<?xml version="1.0"?>

<!DOCTYPE employee [

<!ELEMENT employee (Name, Dept, Title)>

<!ELEMENT Name (#PCDATA)>

<!ELEMENT Dept (#PCDATA)>

<!ELEMENT Title (#PCDATA)>

]>

<employee>

<Name>John Goodman</Name>

<Dept>Manufacturing</Dept>

<Title>Supervisor</Title>

</employee>

XML-схема

• Для включения в документ ссылку на файл схемы нужно указать в корневом элементе соответствующие атрибуты, например:
<? xmlversion ="1.0"?>
< configuration xmlns: xsi = http://www.w3.org/2001/XMLSchema-instance
    xsi: noNamespaceSchemaLocation ="config.xsd">

    …
< /configuration >

• В данном случае в составе корневого элемента содержится информация о том, что при проверке документа должен использоваться файл схемы config.xsd.

• Если применяется пространство имен – синтаксис усложняется.

• Схема определяет тип каждого элемента

• Это может быть простой или сложный тип

• Некоторые простые типы предопределены в XML-схеме:

xsd:string

xsd:int

xsd:boolean

• Можно определять собственные простые типы

• Вместо префикса xsd (обозначает пространство имен XSLSchemaDefinition), можно применять xs:

• Определяя элемент, следует указать его тип:

<xsd:element name="name" type="xsd:string"/>

<xsd:element name=“size" type="xsd:int"/>

• Простые типы можно объединять в сложные:
< xsd : complexTypename = " FontType ">

              <xsd:sequence>

                       <xsd:element ref = "name" />

                       <xsd:element ref = “size" />

                       <xsd:element ref = “style" />

</ xsd : sequence >
</ xsd : complexType >

• FontType – последовательность элементов name, size и style.

• Атрибут ref используется для ссылки на определения, находящиеся в схеме.

• Возможны вложенные определения.

• Для определения атрибутов необходимо включать элементы xsd:attribute.







Dom и SAX

• Для разборки XML-документа необходимо выполнить синтаксический анализ или разбор его содержимого.

Анализатором ( parser ) называется программа, которая считывает файл, подтверждает корректность его формата, разбивает данные на составные элементы и предоставляет программисту доступ к ним.

• Существует два основных типа XML-анализаторов:

§ DOM -анализатор ( DocumentObjectModel ) считывает XML-документ и представляет его в виде древовидной структуры.

§ SAX -анализатор ( SimpleAPIforXML ) генерирует события по мере чтения XML-документа.

• DOM-анализатор представляет документ как древовидную структуру, SAX-анализатор генерирует события в ходе разбора документа.

• При обработке больших документов DOM-анализатор неэффективен, так как требуется память для хранения всей древовидной структуры, SAX-анализатор более экономичный.

• Сформированную древовидную структуру можно многократно и по-разному обходить, при использовании SAX-анализатора события генерируются последовательно в порядке возникновения и повторный обход документа невозможен.

Dom

• Пакет org.w3c.dom содержит определения типов интерфейсов, например, Document и Element.

• Ряд компаний, например, IBM и Apache, разработали собственные варианты DOM-анализаторов, которые реализуют эти интерфейсы.

• В API обработки XML-документов(JavaAPIforXMLProcessing-JAXP) компании Sun предусмотрена возможность подключения данных анализаторов.

• Кроме того, компания Sun включила в состав пакета JDK собственный анализатор.

Для считывания XML-документа потребуется объект DocumentBuilder , который можно получить с помощью класса DocumentBuilderFactory .

DocumentBuilder Factory factory = DocumentBuilder Factory.newInstance();
DocumentBuilder builder = factory.new DocumentBuilder();

File f = … // можноиспользовать URL или InputStream
Document doc = builder.parse(f);

• Объект Documentявляется внутренним представлением древовидной структуры XML-документа.

• Он состоит из экземпляров классов, реализующих интерфейс Node и его дочерние интерфейсы (Attr , Comment , Document , Element , Text).

• Анализ содержимого документа начинается с вызова метода getDocumentElement (), который возвращает корневой элемент
Elementroot  = doc.getDocumentElement();

• Метод getTagName () возвращает имя дескриптора элемента.

•  Для извлечения элементов, дочерних по отношению к данному (вложенных элементов, текста, комментариев или других узлов) предназначен метод getChilNodes (), возвращающий набор данных типа NodeList .

• Метод item () возвращает элемент набора с заданным индексом.

• Метод getLength () возвращает общее количество элементов.

• Методы getFirstChild () и getLastChild () используются для получения первого и последнего дочернего узла.

• Метод getNextSibling () позволяет получить следующий узел того же уровня.

• Метод getAttributes () возвращает карту NameNodeMap с объектами типа Node, описывающими атрибуты.

• Методы getNodeName () и getNodeValue () извлекают имя и значение атрибута соответственно.

•  Метод getAttributes ("имя ") извлекает значение атрибута по имени.

Пример 2

import org.w3c.dom.*;

import javax.xml.parsers.*;

public class MyXml {

    public static void main(String[] args) {

        try {

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

            DocumentBuilder builder = factory.newDocumentBuilder();

            Document doc = builder.parse("G:\\Haulmont\\java_SE\\config.xml");

            System.out.print("The elements are: ");

            printElements(doc);

            System.out.println("The attributes of each element are: ");

            printElementAttributes(doc);

        } catch (Exception e) { System.out.println(e.toString()); }

    }

static void printElements(Document doc) {

        NodeList nl = doc.getElementsByTagName("*");

        for (int i = 0; i < nl.getLength(); i++) {

            System.out.print(nl.item(i).getNodeName() + " ");

        }

        System.out.println();

    }

static void printElementAttributes(Document doc) {

        NodeList nl = doc.getElementsByTagName("*");

        for (int j = 0; j < nl.getLength(); j++) {

            Element e = (Element) nl.item(j);

            System.out.println(e.getTagName() + ":");

            NamedNodeMap nnm = e.getAttributes();

            if (nnm != null) {

                for (int i = 0; i < nnm.getLength(); i++) {

                    Node n = nnm.item(i);

                    System.out.print(" " + n.getNodeName() + " = " + n.getNodeValue());

                }

            }

            System.out.println();

        } } }




SAX

• Для использования SAX-анализатора необходимо создать обработчик событий, которые происходят во время разбора XML-документа.

• В интерфейсе ContentHandlerопределено несколько методов, к которым обращается анализатор:

§ Методы startElement () и endElement () вызываются при получении открывающего и закрывающего дескрипторов.

§ Метод characters () вызывается при получении символьных данных.

§ Методы startDocument () и endDocument () вызываются в начале и в конце документа.

• Для получения SAX-анализатора используется следующая команда:
SAXParserFactoryfactory = SAXParserFactory . newInstance ();

SAXParser parser = factory.newSAXParser();

• Для обработки документа следует использовать команду:

    parser . parse ( source , handler );
Здесь source – это источник входных данных, который может быть файлом, URL или входным потоком;
handler – подкласс класса DefaultHandler , в котором определены методы, объявленные в интерфейсах ContentHandler , DTDHandler , EntityResolver , ErrorHandler .

• Эти методы не выполняют никаких действий.

Пример 3

import java.io.IOException;

import javax.xml.parsers.*;

import org.xml.sax.*;

import org.xml.sax.helpers.*;

class CustomSAXParser extends DefaultHandler{

    public void startDocument() throws SAXException {

         System.out.println("Start parse XML...");

    }

    public void startElement(String namespaceURI, String localName,

                String qName, Attributes atts) throws SAXException {

         System.out.println("Start element " + qName + ":");

    }

    public void endElement(String namespaceURI, String localName,

                String qName) throws SAXException {

         System.out.println("End element " + qName + ":");

    }

    public void endDocument() {

         System.out.println("Stop parse XML...");

    }

    public static void main(String[] args) {

        try {

            SAXParserFactory factory = SAXParserFactory.newInstance();

            SAXParser parser = factory.newSAXParser();

            CustomSAXParser custom = new CustomSAXParser();

            parser.parse("G:\\Haulmont\\java_SE\\config.xml", custom);

        } catch (IOException ex) {

            ex.printStackTrace();

        } catch (ParserConfigurationException ex) {

            ex.printStackTrace();

        } catch (SAXException ex) {

            ex.printStackTrace();

        } } }




Создание XML-документов

• Используется пакет javax . xml . transform .

• Удобнее создать древовидную структуру DOM, представляющую документ, а затем записать содержимое этого дерева в файл.

• В первую очередь следует сгенерировать пустой документ с помощью метода newDocument () класса DocumentBuilder
Documentdoc = builder . newDocument ();

• Затем для создания элементов документа нужно применить метод createElement ()  класса Document
ElementrootElement = doc . createElement ( rootName );
ElementchildElement = doc . createElement ( childName );

• Далее создаем текстовые узлы с помощью метода createTextNode ().

Text textNode = doc.createTextNode(textContents);

• Длявключениявдокументкорневогоэлементаидлясвязываниядочернихузловсродительскимииспользуетсяприведенныйнижекод:
doc.appendChild(rootElement);
rootElement.appendChild(childElement);
childElement.appendChild(textNode);

• Приформированиидерева DOM атрибутыэлементовзадаютсяспомощьюметодаsetAttribute()классаElement
rootElement.setAttribute(name, value);

Для записи дерева DOM в выходной поток к документу применяется преобразование (XSLT-преобразование), в процессе которого не выполняется никаких действий и результат записывается в выходной поток.

• Для включения узла DOCTYPE в состав выходных данных нужно указать в качестве свойств идентификаторы SYSTEM и PUBLIC
Transformer t = Transformer Factory . newInstance (). newTransformer ();
t .setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, system Identifier );
t .setOutputProperty(OutputKeys.DOCTYPE_ PUBLIC , publicIdentifier );
t . transform ( newDOMSource ( doc ), newStreamResult ( new FileOutputStream ( file )));

Пример 4

import org.w3c.dom.*;

import javax.xml.parsers.*;

import javax.xml.transform.*;

import javax.xml.transform.dom.*;

import javax.xml.transform.stream.*;

import java.io.*;

public class WriteXML {

public static void main(String[] args) {

   try {

      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

      DocumentBuilder builder = factory.newDocumentBuilder();

      Document doc = builder.parse("G:\\Haulmont\\java_SE\\config.xml");

Transformer t = TransformerFactory.newInstance().newTransformer();

t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());

FileOutputStream f = new FileOutputStream("G:\\Haulmont\\java_SE\\config1.xml");

t.transform(new DOMSource(doc), new StreamResult (f));

} catch (Exception e) {

        e.printStackTrace();

}

}

}


 













Hibernate

ORM (Object-relational mapping) — это отображение объектов какого-либо объектно-ориентированного языка в структуры реляционных баз данных.

Преимущества ORM

• Нет необходимости писать рутинные insert/update/delete/select для CRUD(create, read, update, delete) операций.

• Условия связи между объектами (строками таблиц) указываются декларативно в одном месте.

• Возможность использовать полиморфные запросы для иерархий классов.

• Высокая степень независимости от конкретной СУБД.

Недостатки ORM

• Возможны проблемы с производительностью для сложных запросов на объектном SQL.

• Затрудняет использование специфических конструкций языка SQL конкретной СУБД.

• Потеря объектно-реляционного соответствия.

ORM-решением для языкаJava является технологияHibernate, которая не только связывает Java классы с таблицами базы данных, но также предоставляет средства для автоматического построения запросов и извлечения данных и может значительно уменьшить время разработки, которое обычно тратится на ручное написание SQL иJDBCкода. Hibernate генерирует SQL вызовы и освобождает разработчика от ручной обработки результирующего набора данных и конвертации объектов.

Mapping (сопоставление, проецирование) Java-классов с таблицами БД осуществляется с помощью конфигурационныхXMLфайлов илиJava-аннотаций. Обеспечиваются возможности по организации отношений между классами «один-ко-многим» и «многие-ко-многим».

Для применения Hibernate на практике во-первых, необходимо описать XMLфайл, содержащий информацию о настройках связи с БД и о способе Mapping.Располагаться он должен в самом корне дерева классов.

Пример 5

Файлhibernate.cfg.xml.

<hibernate-configuration>

<session-factory>

<!-- PostgreSQL connection settings -->

<property name="connection.driver_class">org.postgresql.Driver</property>

<property name="connection.url">jdbc:postgresql://localhost:5433/orm</property>

<property name="connection.username">postgres</property>

<property name="connection.password">sa</property>

<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>

<property name="hbm2ddl.auto">update</property>

<!-- Other hibernate settings -->

<property name="show_sql">true</property>

<!-- Annotated classes (Mapping from Annotations) -->

<mapping package="org.haulmont.catalog.model"/>

<mapping class="org.haulmont.catalog.model.Shop"/>

<mapping class="org.haulmont.catalog.model.Book"/>

<mapping class="org.haulmont.catalog.model.Magazine"/>

<mapping class="org.haulmont.catalog.model.Author"/>

<!-- Mapping from configuration file (as an alternative to annotations) -->

<!--<mapping resource="mapping.hbm.xml"/>-->

</session-factory>

</hibernate-configuration>

§ connection.driver_classПоказывает класс драйвера, который используется для соединения с базой данных.

§ connection.url –URL для соединения с базой данных.

§ connection.username– логин к базе данных.

§ connection.password– пароль к базе данных.

§ dialect– т.к. Hibernate может работать с разными базами данных, и каждая имеет какие-то особенности (генерация первичного ключа, страничный вывод, функции), нам надо указать, с какой базой мы работаем. В данном случае у нас PostgreSQL, что мы и указываем.

§ hbm2ddl.auto - свойство, которое указывается что нужно сделать со схемой БД при инициализации. Может принимать такие значения:
update - сверяет схему БД с имеющимися конфигурациями классов, если мы внесли какие-то изменения, они автоматически занесуться в БД. При этом данные, которые были занесены в базу не изменятся - даже, если мы решили удалить некоторые поля из таблицы, они все одно останутся;

create - каждый раз при запуске приложения, схема БД будет создаваться наново. Все данные, которые были занесены раньше, будут удалены;

create-drop - каждый раз при запуске приложения, схема БД будет создаваться наново, а при завершении - удаляться. Все данные, которые были занесены во время работы приложения, будут удалены по завершению приложения;

validate - при инициализации будет совершена проверка соответствуют ли конфигурации классов и схема БД. Если мы внесли изменение в конфигурацию какого-то класса, а схема в БД не была изменена, выбросится исключение;

§ show_sql– данное свойство указывает, будут ли выводится SQL-запросы, которые генерит Hibernate на консоль. В процессе отладки это бывает очень удобно.

§ тэг – mapping. Он используется для перечисления всех классов, которые имеют связь с базой данных. Т.е. если вы хотите использовать какой-то класс для связи с какой-то таблицей, вы должны его здесь указать.

Во-вторых, нужноописатьклассы для работы с данными.

Пример 6





§ Класс Shop связан с таблицей SHOP .

§  Первичный ключ – ID, связан со свойством id (функции getId ()/setId ()).

§  Для генерации значений первичного ключа ID используется sequenceSEQ _ ID .

§  Атрибут NAME связан со свойством name (функции getName ()/setName ()).

§  Объекты Shop содержат список Item:

§  связь “один-ко-многим” (@ OneToMany)

§  обязательная (nullable=false)

§  Внешний ключ, определяющий связь – SHOP _ ID .

§  Список Item загружаются по требованию (FetchType . LAZY).

§  При сохранении объекта Shop автоматически сохраняются все его items (CascadeType . ALL).

Рассмотрим подробнее используемые аннотации:

§ @Entity– говорит о том, что данный класс представляет собой сущность, которую надо сохранять в базе данных.

§ @Table– показывает, какая таблица используется для хранения.

§ @Id– говорит о том, что данное поле является идентификатором.

§ @GeneratedValue– аннотация дает указание, что данная величина будет генериться.

§ @Column–аннотация для указания имени столбца, с которым связано поле класса.

§ @JoinColumn – данная анотация по сути похожа на @Column. Только она указывает, что колонка является связующей.

§ @ManyToOne – аннотация указывает, что поле указывает на другой класс, который связан с текущим классом связью многие-к-одному. Здесь также указывается правило каскадаcascade= CascadeType.REFRESH– в упрощенном виде оно гласит “что сделали с тобой, то сделай и со связью. CascadeType.ALLобозначает выполнение каскадных операций при save-update и delete, по умолчанию Hibernate будетигнорировать ассоциации, поэтому “разруливать” зависимости придется самостоятельно. Запись fetch=FetchType.LAZY указывает, что загрузка данного поля будет только в случае обращения к данному полю. Пока программа этого не делает, поле будет пустым.

§ @OneToMany– такая запись говорит о том, что поле служить для связи один-ко-многим (потому и список).

§ @ManyToMany– эта аннотация говорит о том, что поле будет использовано для связи много-ко-многим.

§ @JoinTable– указывает имя таблицы, которая используется для организации связи много-ко-многим. Параметр joinColumns указывает название столбца, который является ссылкой на текущий класс, параметр inverseJoinColumns указывает на колонку, в которой находится ссылка на класс с другой стороны.

В качестве альтернативы аннотациям возможно использование XML-файла с настройками (файл mapping.cfg.xml.). Во-третьих, нужноописатькласс для работы с HibernateAPI.

§ Работая с данными в объектно-ориентированном языке, мы работаем с объектами, заполняя и считывая значения полей, создавая новые или изменяя существующие объекты, определяя зависимости между объектами.

§ При операции save () мы передаем объект типа Shop, который сохраняется в базу данных по описанным правилам отображения. В том числе сохраняются и все зависимые объекты (Item).

§  Составляя запросы к базе данных, мы уже указываем не столбцы таблицы, а свойства объектов.

Обратите внимание на работу с транзакциями: начало транзакции( метод beginTransaction()), подтверждение транзакции (метод commit()), откат транзакции (метод rollback()).

Пример 7, 8

 


 

 








Servlets

Servlet (сервлет) – это класс на Java, расширяющий возможности сервера, к которому происходят обращения в рамках модели «запрос-отклик». Теоретическиможет поддерживать любой тип запросов, но чаще всего используются HTTP-сервлеты.

Servlet container(контейнер сервлета) - контейнер, обеспечивающий сетевые службы, при помощи которых посылаются запросы и ответы, декодируются запросы и форматируются ответы.Все контейнеры сервлетов должны поддерживать HTTPпротокол, но могут также поддерживать дополнительные протоколы, например, HTTPS.

Distributed servlet container (распределенный контейнер сервлета)- контейнер сервлета, запускающий Web-приложения, которые помечены как распределенные и выполняются на нескольких виртуальных машинах Java. При этом виртуальные машины могут быть запущены, как на одном, так и на разных компьютерах.

Servlet context (контекст сервлета) - объект, содержащий представление(вид) Web-приложения,в котором запущен сервлет. Используя контекст, сервлет может вести журнал событий, получать URL-ссылки на ресурсы,а также устанавливать и хранить атрибуты, которые могут использоваться другими сервлетами в приложении.

Servlet mapping (отображение сервлета)- определяет связь между структурой URL и сервлетом. Используется для отображения запросов в сервлеты. Если контейнер, обрабатывающий запрос, является JSP-контейнером, то неявно отображается URL,содержащий расширение.jsp.

Жизненный цикл сервлета

· Если экземпляр сервлета не существует, то контейнер:

1. загружает класс сервлета;

2. создает его экземпляр;

3. вызывает метод init() .

· При получении запроса вызывается метод service(), которому передаются объекты запроса и отклика.

· Если контейнеру требуется удалить объект сервлета, то вызывается метод destroy().

Особенности сервлетов

· Существуют механизмы реагирования на события, связанные с деятельностью сервлетов в приложении:

l javax.servlet. Событие Listener

l javax.servlet. Событие Event

· Для обработки события требуется:

l написать класс, реализующий интерфейс.

l снабдить этот класс аннотацией @ WebListener(пакет javax . servlet . annotation).

· Требуется учитывать то, что сервлет является разделяемым ресурсом и работает с разделяемыми ресурсами.

· Не следует использовать поля класса для хранения состояния, а особенно для передачи состояния между вызовами.

Объект запроса

· Реализует интерфейс javax.servlet.ServletRequest.

· Позволяет узнать характеристики запроса, в том числе значения параметров:

l String getParameter(String name)

l Enumeration getParameterNames()

l и ряд других методов

· Позволяет получить доступ к потоку запроса:

l ServletInputStream getInputStream()

l BufferedReader getReader()

l Можно вызвать только один из этих двух методов

· Позволяет получить параметры запроса

l int getContentLength()

l String getContentType()

l String getProtocol()

l и т.д.

Объект отклика

· Реализует интерфейс javax.servlet.ServletResponse

· Основные методы:

l ServletOutputStream getOutputStream()
Далее для вывода используются обычные средства бинарного вывода

l PrintWriter getWriter()
Далее для вывода используются обычные средства символьного вывода

l Можно вызвать только один из этих двух методов.

· Позволяет установить параметры отклика

l Для установки типа отклика используется метод setContentType ()

l Для установки кодировки используется метод setCharacterEncoding ()

l Сбрасывает текущий буфер клиентуflushBuffer ()

l Очищает буфер и сбрасывает статус reset ()



HTTP Servlet

· javax.servlet.http.HttpServlet - абстрактный класс, позволяющий создавать сервлеты, удобные для Web.

· Наследные классы должны переопределять хотя бы один из методов обработки запроса.

· Обычно это один из методов:

l void doGet(HttpServletRequest req, HttpServletResponse resp)

l void doPost(HttpServletRequest req, HttpServletResponse resp)

· Классы снабжаются аннотацией @WebServlet.

Пример 9. Класс сервлета

importjava.io.*;

importjavax.servlet.*;

importjavax.servlet.http.*;

importjavax.servlet.annotation.*;

@WebServlet("/MyServlet.html")

public class MyServlet extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {

PrintWriter out = response.getWriter();

try {

out.print("<html><body>This is text document, which has "

            + "<a href=\"other.html\">link</a>"

            + " to another document</body></html>");

}

finally {

out.close(); }

}

}

Поддержка сессий

· В HTTP-сервлетах в объектах запроса и отклика добавляются дополнительные методы.

· Среди них появляются методы работы с сессиями, включая работу с Cookies(англ. печенье) - небольшой фрагмент данных, отправленный веб-сервером и хранимый на компьютере пользователя. Веб-клиент (обычно веб-браузер) всякий раз при попытке открыть страницу соответствующего сайта пересылает этот фрагмент данных веб-серверу в составе HTTP-запроса. Применяется для сохранения данных на стороне пользователя, на практике обычно используется для аутентификации пользователя, хранения персональных предпочтений и настроек пользователя, отслеживания состояния сеанса доступа пользователя, ведения статистики опользователях.

· Для передачи значений между запросами можно использовать атрибуты сессии.

l HttpSession.getAttribute(String name)

l HttpSession.setAttribute(String name, Object value)

l И ряд других методов

Пример 1 0 .

public class CashierServlet extends HttpServlet {

public void doGet (HttpServletRequest request,

                HttpServletResponse response)

                throws ServletException, IOException {

// Get the user's session and shopping cart

HttpSession session = request.getSession();

ShoppingCart cart =(ShoppingCart)session.getAttribute("cart");

//...

}

}

out.println("<a href=\"" +

response.encodeURL(request.getContextPath() +

"/bookcatalog") + "\">");

Дата: 2019-02-19, просмотров: 302.