sonyps4.ru

Delphi параметры по умолчанию. Использование процедур и функций в Delphi

JSP (Java server pages) — это технология, которая позволяет внедрять Java-код, а также EL (expression language) в статичное содержимое страницы) и позволяющая веб-разработчикам динамически генерировать HTML, XML и другие веб-страницы. JSP является составной частью единой технологии создания бизнес-приложений J2EE.

JSP — может выполняться практически на любом веб сервере, так как эта технология основана на языке программирования Java, который не зависит от платформы. Java server pages поддерживает теги HTML, Javascript, а также собственный набор тегов.

JSP — позволяет отделить динамическую часть страницы от статической. Эта технология предусматривает вставку Java кода в страницу. Мы не будем рассматривать такой вариант использования JSP поскольку эта технология считается устаревшей и несовершенной. Причина проста: разработчики дизайнеры, которые разрабатывают внешний вид страницы не всегда могут быть знакомы с Java и это может вызвать дополнительные трудности при редактировании или поддержке веб приложений.

Вместо вставки Java кода сейчас используется библиотека тегов jstl или Javascript для совсем продвинутых. Мы рассмотрим пример именно с jstl тегами. Это очень удобная библиотека, которая имеет почти весь функционал, который необходим при создании динамических страниц. Если нужно что-то специфическое, то всегда можно написать собственный тег и вставить его содержимое на страницу.

Мы уже частично знакомы с JSP по первым . Основная часть JSP страницы это HTML, в которую вставляются теги с динамическим содержимым.

Пример JSP страницы

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

Директива JSP — это сообщение, которое страница может послать соответствующему контейнеру с указанием действий. Синтаксис директивы:<% @ атрибут = «значение» %>

Есть три основных типа директив:

  1. page (может использоваться для импорта классов);
  2. include (дает вам возможность вставить файл в класс сервлета при трансляции JSP файла в сервлет);
  3. taglib (дает возможность подключить библиотеку тегов).

Так, как код в страницу мы вставлять не будем, рассмотрим последние две директивы.

Например у нас есть страницы, которые будут иметь одинаковую верхнюю и нижнюю часть. Очень распространенный шаблон, в котором футер и хедер одинаковы для всех страниц. Для того, чтобы не писать Код этих страниц в каждом JSP файле можно вынести их код в отдельный файлы и потом подключить в нужном нам месте с помощью директивы include.

Расположение файлов в проекте:

В коде выше можно проследить использование директивы taglib. С ее помощью мы подключили библиотеку тегов jstl. С помощью этой директивы можно подключить библиотеку собственных тегов: <%@ taglib uri=»/WEB-INF/mylib.tld» prefix=»test» %>.

Заметьте, что важным атрибутом taglib является prefix. Это обязательный к использованию атрибут. С помощью prefix можно вызывать библиотеку в коде. Имя prefix можно выбирать любое. К стати, вот и использование jstl тегов на деле:

    < c: forEach items= "${accounts} " var = "account" >

    < tr align= "center" >

    < td> ${ account. number}

    < td> ${ account. balance}

    < td>< c: if test= "${!account.isBlocked}" > ${ statusActive }

    < c: if test= "${account.isBlocked}" > ${ statusBlocked }

    < td>< c: if test= "${!account.isBlocked}" >

    < a href= "?command=blockaccount&accountId=${account.accountId}" > ${ block }

    < td>< a href= "?command=showinfo&accountId=${account.accountId}" > ${ showInfo }

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

${item}

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

Синтаксис:
a equals b

Лучше всего рассматривать теги jstl при написании реального проекта, так как я не вижу смысла учить и запоминать весь синтаксис для каждого действия. Код выше должен послужить только примером, как это используется. Не нужно ничего заучивать. Когда Вы будете писать код, тогда и обратитесь к данному синтаксису.

К стати, код проекта, с которого был взят этот код, находится тут: https://github.com/caligula95/payment-systemapp

Я выложил проект на heroku: https://payment-systemapp.herokuapp.com/ — тут используется бесплатный аккаунт, так что для первого запроса нужно подождать пару минут, чтобы проект запустился.

13.05.05 14.8K

Введение

Технология Java Server Pages (JSP) является составной частью единой технологии создания бизнес-приложений J2EE. JSP — это альтернативная методика разработки приложений, динамически генерирующих ответ на те или иные запросы клиента. Прежде чем JSP документ будет использован, специальная процедура преобразует его в соответствующий сервлет. В свою очередь, сервлет, как правило, пишется на языке Java и реализует определенный интерфейс. Далее, сервлет также не является самостоятельным приложением и функционирует, только будучи помещен в соответствующий web-контейнер. Web-контейнер обеспечивает обмен данными между сервлетом и клиентами, берет на себя выполнение таких функций, как создание программной среды для функционирующего сервлета, идентификацию и авторизацию клиентов, организацию сессии для каждого из них.

На настоящий момент реализована трансляция JSP страницы в сервлет, программный код которого пишется на языке Java. Однако авторы спецификации Java Server Pages оставляют возможность реализации JSP и на других языках программирования.

Соотношение между сервлетами бизнес-приложения и адресами URL на сервере задается в дескрипторе размещения. Технология реализации сервлетов обсуждается в отдельной статье. Сейчас же важно отметить тот факт, что программный код, используемый для написания сервлетов, не всегда удобен для динамической генерации текстовых документов в ответ на запрос клиента. Например, фрагмент сервлета, где осуществляется генерация динамической HTML страницы, может выглядеть следующим образом:

PrintWriter out = res.getWriter(); out.println(""); out.println(""); ... out.println(""); out.println(""); out.close();

Как видим, каждой строке HTML документа в сервлете соответствует определенный фрагмент программного кода, что не способствует простоте разработки и сопровождения бизнес-приложений.

Удобнее разделить динамическую и статическую части генерируемой web-страницы. Для создания динамической части по-прежнему будет использоваться Java или другой язык программирования. Статическую же часть имеет смысл оформить как текстовый документ — Java Server Page (JSP страницу), оформленную в соответствии с требованиями HTML, XML или другого стандарта разметки. Фактически, JSP страница можно рассматривать как шаблон или прообраз динамической страницы, которую остается дополнить динамическими элементами. Для описания динамической составляющей, в технологии JSP предусмотрено два основных механизма: компоненты JavaBean и библиотеки дополнительных тэгов. Как результат, технология JSP предполагает параллельную работу над приложением двух разных специалистов: программиста и ответственного за верстку документов (web мастера), которые отвечают, соответственно, за разработку динамической и статической частей документов, генерируемых в ответ на запросы клиентов.

Как уже говорилось, перед тем, как использовать JSP страницу, ее необходимо преобразовать в соответствующий сервлет. Такое преобразование может выполняться либо в момент, когда JSP страница помещается на сервер, либо когда клиент первый раз обращается к этой странице. Поскольку процедура преобразования довольно трудоемка и занимает много времени, то выполняется она обычно только один раз. Все же последующие обращения клиента к JSP странице сервер автоматически переадресует на сервлет, который был получен в результате ее преобразования.

Сервлет, полученный после преобразования JSP страницы, функционируют в рамках стандартного контейнера сервлетов и используют строго регламентированный интерфейс. Поэтому эта технология не зависит от каких-либо особенностей той или иной аппаратной платформы. С другой стороны, поскольку JSP технологии может строиться на базе интерпретируемого языка Java, то это дает гарантию портируемости приложений, построенных на технологии JSP, на любую платформу, где можно установить виртуальную Java машину.

JSP страница

Как правило, JSP страница хранится в отдельном файле с расширением.jsp. Большая часть содержимого JSP страницы преобразуется в сервлете в набор инструкций out.println(). Пример JSP страницы:

<%@ taglib uri="/exttags.tld" prefix="dscat" %> <%@ page import = "xbcat.util.*" %> All Customers <% Vector menu=pagescroll.getMenu(); if(pagescroll.page.size() > 0) { %>

<%= pagescroll.getTotalPages() %> <% if(!pagescroll.isSinglePage()) { for(int i=0; i "><%= name %> <% } else { %> <%= name %> <% } } } %>

Динамическая составляющая JSP страницы представлена тремя типами специальных элементов: директивами, action и скриптами. Подробнее каждый из них рассматривается в соответствующем разделе.

Директивы

Поскольку web контейнер, прежде чем использовать JSP страницу, предоставленную разработчиками бизнес-приложения, транслирует ее в соответствующий сервлет, имеет смысл предоставить возможность оставлять на JSP странице директивы, которые будут управлять процессом трансляции. Директивы имеют синтаксис

<%@ директива... %>

Рассмотрим некоторые из таких директив

Директива page. Декларирует ряд свойств JSP страницы. Синтаксис директивы:

<%@ page список_параметров %>

Опишем некоторые наиболее интересные параметры данной директивы:

  • import — Как уже говорилось, JSP страница перед использованием должна быть преобразована в программный код — класс, соответствующего сервлета. В свою очередь, класс сервлета может обращаться к другим классам из стандартных библиотек Java или классам из других пакетов. По умолчанию, класс сервлета, получаемый после трансляции JSP страницы, может иметь связь с пакетами java.lang, java.servlet, java.servlet.jsp и java.servlet.http. Если для класса сервлета требуется обеспечить связь с другими пакетами, например, с xbcat.util как в приведенном выше примере JSP страницы, последнюю следует дополнить директивой page, имеющей атрибут import с названием соответствующего пакета.
  • session — Если для связи с клиентом используется протокол HTTP, то для каждого сеанса по умолчанию создается объект session, позволяющий сохранять информацию об этом клиенте в интервале между его обращениями к серверу. С другой стороны, если атрибут session был указан со значением false, это позволяет отказаться от создания объекта сессии и использовать освободившиеся ресурсы сервера для решения других задач.
  • buffer — Содержимое страницы, созданной в ответ на запрос клиента, сервлет передает в поток вывода out, откуда оно затем передается web контейнером непосредственно клиенту. Чтобы получить более оптимальный режим передачи, в этом потоке предусмотрен режим буферизации. При этом объем буфера по умолчанию составляет 8 килобайт. Параметр buffer директивы page позволяет либо задать другой объем буфера, либо вообще отказаться от режима буферизации, передав атрибуту значение «none».
  • isThreadSafe — Согласно спецификации сервлетов, web контейнер по умолчанию позволяет одному и тому же экземпляру сервлета параллельно обрабатывать запросы сразу от нескольких клиентов. При этом каждому из запросов выделяется отдельный трэд. Между тем, в некоторых случаях бывает полезно запретить параллельную обработку запросов. (Соответствующий контроллер в web контейнере выстраивает приходящие запросы в очередь и передает их сервлету на обработку строго по одному.) Для этого достаточно использовать атрибут isThreadSafe, со значением false.
  • pageEncoding — Позволяет разработчику приложения декларировать кодировку, которая должна использоваться в документе, передаваемом клиенту. По умолчанию считается, что страница имеет кодировку ISO-8859-1.
  • contentType — В ответ на запрос клиента, JSP страница по умолчанию генерирует документ типа HTML. Вместе с тем, область применения технологии Java Server Pages гораздо шире, поскольку она позволяет генерировать любые другие типы текстовых документов: XML, WML, VRML и т.д. MIME-тип генерируемого документа декларируется атрибутом contentType. Как уже понятно, по умолчанию этот атрибут имеет значение «test/html». Вместе с типом документа, спецификация JSP позволяет в том же атрибуте указывать также кодировку генерируемого документа.

Директива taglib. Позволяет использовать на JSP страницах дополнительные тэги, созданные разработчиком приложения (custom тэги). Синтаксис директивы:

<%@ taglib uri="URI библиотеки тэгов" prefix="имя префикса" %>

где, uri — абсолютный или относительный адрес URI, уникальным образом идентифицирующий дескриптор библиотеки тэгов, связанных с указанным префиксом. Указанный префикс используется для идентификации соответствующих custom тэгов.

<%@ taglib uri="http://www.mycorp/supertags" prefix="super" %> ... ... ...

Процедуру создания custom тэгов мы рассмотрим позднее.

Директива include. Используется для помещения в JSP страницу текстов и программного кода из других источников. Подстановка выполняется в момент, трансляции JSP страницы в соответствующий сервлет. Пример использования директивы:

<%@ include file="menu.jsp" %>

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

Фрагмент программного кода на JSP странице (скрипт)

Скрипт, как и остальные элементы, привносит в конечный документ динамическую составляющую. Однако, в отличие от них, скрипт — программный код, помещенный непосредственно в текст JSP страницы. Скрипт может производить вычисления или манипулировать объектами, что позволяет наглядно связывать характеристики генерируемой страницы с параметрами запроса клиента и бизнес-правилами приложения. Элементы скриптов бывают трех типов: декларации, скриплеты и выражения.

Декларации

После преобразования JSP страницы в сервлет большая часть ее содержимого попадает в метод _jspService(), который вызывается всякий раз, когда появляется необходимость обработать заказ клиента. Декларация на JSP странице чаще всего используется для того, чтобы объявить дополнительные атрибуты и методы в классе сервлета, которые будут доступны при обработке любого запроса клиента. Декларации имеют синтаксис <%! … %> .

Примеры деклараций на JSP странице:

<%! int i; %> <%! int i = 0; %> <%! public String f(int i) { ... } %>

Скриплеты

Скриплет может содержать программный код и декларации локальных переменных, которые будут использованы для обработки запросов клиентов. Фактически, скриплет — это фрагмент программного кода из будущего сервлета, который в свое время будет помещен в метод _jspService(). Являясь частью сервлета, скриплет получает доступ к объекту response и, соответственно, может самостоятельно формировать определенную часть конечной динамической страницы. Однако чаще всего скриплеты используются не для этого, а для того, чтобы управлять объектами бизнес-логики и логикой приложения.

Скриплет имеет синтаксис <% … %> . Пример использования скриплетов в содержимом JSP страницы:

<% if (i == 0) { %> Good morning <% } else { %> Good afternoon <% } %>

Чтобы оценить наглядность и простоту этой конструкции, сравните ее с эквивалентным фрагментом программного кода в сервлете:

if (i == 0) { out.println("Good morning"); } else { out.println("Good afternoon"); }

Выражения

Часто страница, передаваемая клиенту, содержит результаты вычислений или обращений к тем или иным методам и атрибутам определенных классов. Любой из таких динамических элементов можно преобразовать в строку и представить на JSP странице с помощью вызова out.println в соответствующем скриплете:

<% UserProfile user = (UserProfile) session.getValue("Profile"); %> <% out.println(user.getFaxNumber()); %>

Вторую строку в приведенном примере удобнее и нагляднее представить в боле кратном виде, используя синтаксис выражения <%= … %> :

<%= user.getFaxNumber() %>

Другой пример использования выражения в теле JSP страницы:

<%! int i = 0; %> Hi, now the servlet processing <%= ++i %>th request.

JSP страницы и объекты

В ходе обработки запросов, JSP страница может получать доступ к объектам, расположенным на сервере, создавать их и модифицировать. Доступ к объектам осуществляется через элементы скриптов и action. Каждый создаваемый в приложении объект имеет определенное время существования, которое декларируется в соответствующем атрибуте. Спецификацией предусматривается четыре интервала:

  • page — Объект, чье время существования определяется как page, доступен в пределах только той JSP страницы, где он был создан. Все ссылки на этот объект должны быть освобождены сразу же после того, как запрос клиента был обработан.
  • request — Объект, чье время существования определяется как request, доступен для всех страниц, связанных с обработкой данного запроса. В частности, если имеет место переадресация обработки на новую JSP страницу, данный объект будет доступен и на прежней, и на новой странице. Как и в предыдущем случае, ссылки на объект после обработки запроса должны быть освобождены.
  • session — Объект с областью видимости session доступен для всех страниц, обрабатывающих запросы, связанные с определенной сессией (сеансом связи с конкретным клиентом). Ссылки на объекты, связанные с сессией, помещаются в объект session. По окончании сеанса связи ссылки должны быть освобождены.
  • application — Наиболее общая область видимости. Объекты, имеющие область существования application, не привязаны к какой-либо отдельной странице или сеансу связи и доступны со всех JSP страниц данного приложения.

JSP страница всегда имеет доступ к определенному набору объектов, создаваемых web контейнером по умолчанию:

  • request — Объект, содержащий запрос клиента. Относится к классу javax.servlet.ServletRequest или другому наследующему его классу. Например, для протокола HTTP это будет объект класса javax.servlet.http.HttpServletRequest. Область видимости объекта — request.
  • response — Объект, в который сервлет будет помещать ответ на запрос пользователя. Относится к классу javax.servlet.ServletResponse или другому наследующему его классу. Например, для протокола HTTP это будет объект класса javax.servlet.http.HttpServletResponse. Область видимости объекта — request.
  • pageContext — Объект, определяющий контекст JSP страницы. Область видимости объекта — page
  • session — Объект, создаваемый контейнером для идентификации клиента, а также хранения персональных объектов. Создается контейнером для протокола HTTP и является экземпляром класса javax.servlet.http.HttpSession.
  • application — Объект, связанный с конфигурацией сервлета, соответствующего данной JSP странице. Область видимости объекта — application.
  • out — Объект, содержащий выходной поток сервлета. Информация, посылаемая в этот поток, будет передана клиенту. Объект является экземпляром класса javax.servlet.jsp.JspWriter. Например, большая часть статического шаблона на JSP странице, в идеале, должна быть записана в виде соответствующего набора команд out.println(). Область видимости объекта — page.
  • config — Объект, связанный с конфигурацией сервлета. Является экземпляром класса javax.servlet.ServletConfig. Для JSP страницы область видимости объекта config — page.
  • page — Объект, связанный с обработкой данной страницы. Область видимости — page

Элементы action

Независимо от того, какой тип будет иметь документ, генерируемый в ответ на запрос пользователя, в общем случае, JSP страница содержит текст и тэги. Очевидно, что последние соответствуют типу генерируемого документа: HTML, XML и т.д. Кроме того, в теле JSP страницы могут содержаться фрагменты программного кода на языке Java, которые должны войти в состав сервлета, получаемого после трансляции: декларации, скриплеты и выражения. Идея заключается в том, чтобы дополнить набор тэгов стандартной разметки специальными тэгами — элементами action, за которыми разработчик бизнес-приложения может скрыть часть программного кода, относящегося к приложению, либо некоторые дополнительные инструкции.

Заметим, что с точки зрения специалиста по верстке документов, элементы action являются такими же тэгами, как и все остальные, а потому допустимо их совместное использование с другими элементами:

Рассмотрим некоторые из этих элементов.

Стандартные элементы action

Стандартные элементы action выглядят как обычные тэги, название которых начинается с сочетания символов jsp:, например . Согласно терминологии XML, это означает, что стандартные элементы action в технологии JSP принадлежат пространству имен jsp.

jsp:useBean

Элемент jsp:useBean позволяет использовать на JSP странице объекты, соответствующие компонентам JavaBean. Элемент содержит параметр, который связывает с компонентом некий уникальный идентификатор. Последний затем будет использоваться при обращениях к этому объекту:

В данном примере создается объект класса com.myco. В дальнейшем, чтобы обратиться к нему, достаточно воспользоваться идентификатором «customer». Например:

<%= customer.getName() %>

По умолчанию, объекты, связанные с элементом JavaBean, по умолчанию имеют область видимости page. Разработчик JSP страницы может указать более продолжительное время существования объекта JavaBean, воспользовавшись при написании элемента jsp:useBean элементом scope. Возможные значения этого атрибута — page, request, session и application — мы обсуждали несколько ранее во время разговора об области видимости объектов, связанных с JSP страницей.

Мы не будем рассматривать остальные атрибуты элемента jsp:useBean. Приведем лишь еще один пример его использования:

Внутреннее устройство элементов JavaBean будет рассмотрено нами в отдельной статье.

jsp:setProperty и jsp:getProperty

Любой класс должен давать доступ к некоторым из своих атрибутов и методов. Отличие элемента JavaBean заключается в том, что доступ к атрибутам у него унифицирован и реализуется на JSP странице с помощью элементов jsp:setProperty и jsp:getProperty.

Элемент jsp:getProperty берет экземпляр Bean, извлекает значение указанного атрибута, преобразует его в случае необходимости в строку и помещает в поток данных, передаваемых клиенту. Например, согласно следующей записи

в генерируемый документ помещается значение свойства name из экземпляра Bean, имеющего идентификатор user.

Элемент jsp:setProperty, в отличие от предыдущего, не извлекает, а задает новое значение атрибута. Например:

Помимо явного задания новых значений, элемент jsp:setProperty позволяет заносить в атрибут объекта значение, извлеченное из запроса клиента. Например:

Данная запись означает, что среди данных, полученных от клиента, находится параметр login и его значение передается для помещения в атрибут name объекта Bean, имеющего идентификатор «user».

Наконец, когда названия полей в запросе клиента совпадают с названиями атрибутов объекта Bean, предусмотрен еще один вариант, когда разом осуществляется перенос всех значений. Например:

jsp:include

Подобно директиве include, данный элемент позволяет помещать в тело динамически генерируемой страницы статический и динамический материал из внешнего источника. При этом, хотя заимствованный таким образом материал обрабатывается в том же контексте, что и текущая страница, ему предоставляется доступ только к выходному потоку сервлета. Например, код, включаемый в JSP страницу, не должен обращаться к cookies или использовать собственные заголовки, декларирующие кодировку или тип документа.

Отличие директивы include от элемента jsp:include заключается в том, что для нее включаемый материал не может быть динамическим, а поиск и обработка возможных динамических фрагментов осуществляется не отдельно, а после включения, со всей страницей.

Пример использования элемента jsp:include:

jsp:forward

Данный элемент позволяет переадресовать дальнейшее формирование динамической страницы на другую JSP страницу, сервлет или использовать для завершения заранее приготовленный текст. Например:

В следующем, более сложном примере динамическая страница завершается содержимым текстового файла, название которого берется из переменной someValue:

В заключение следует заметить, что есть две основные схемы обработки запросов клиента:

В первом случае, обработка запроса клиента и формирование в ответ динамической страницы производятся в рамках одной JSP страницы или сервлета. Последняя, в случае необходимости, может обращаться к объектам JavaBean или импортировать материал из внешних источников с помощью директивы include или элемента jsp:include.

Во втором случае, обработка производится в два этапа. Сперва управление подается на сервлет или JPS страницу, осуществляющую собственно обработку запроса. Например, из запроса клиента извлекаются данные и помещаются в базу данных или атрибуты определенных объектов. Затем управление передается на отдельную JSP страницу или сервлет, ответственные за генерацию динамической страницы для последующей передачи ее клиенту. При этом между обработкой запроса и генерацией новой страницы необязательно должна существовать какая-либо взаимосвязь. Например, это может быть всего лишь возврат клиента на главную страницу по завершении какой-либо процедуры.

Дополнительные наборы тэгов

Введение

Такие протоколы разметки текстовых документов, как HTML, имеют строго регламентированный набор тэгов. Вместе с тем, в ходе разработки документов часто возникает потребность использовать дополнительные, специальные тэги, которые хотя и не были заявлены в соответствующие спецификации, но зато в большей степени соответствуют предметной области бизнес-приложения. С одной стороны, подобные дополнительные или custom тэги можно рассматривать как своеобразные макросы, которые перед передачей документа клиенту будут заменены эквивалентной комбинацией стандартных тэгов. В другом варианте, за custom тэгом может стоять определенный фрагмент программного кода. Например, вполне обычный одинарный тэг может оказаться счетчиком посещений или меню, содержимое которого зависит от той роли, которую данный клиент играет в бизнес-процессе.

Построение custom тэгов связано с написанием определенного программного кода. Технология JSP предусматривает размещение этого кода в отдельном программном модуле — библиотеке custom тэгов. Разработка подобных библиотек может быть поручена сторонним компаниям. Подключение JSP страницы к той или иной библиотеке custom тэгов осуществляется с помощью ранее описанной директивы taglib. Указанная директива связывает дескриптор соответствующей библиотеки с определенным префиксом, который, в свою очередь, идентифицирует в теле JSP страницы все custom тэги из данной библиотеки. Так, директива

<%@ taglib uri="/exttags.tld" prefix="dscat" %>

объявляет, что в JSP странице используется библиотека дополнительных тэгов, название каждого из которых начинается с префикса dscat. Например:

All Customers

Программный код данной библиотеки описывается дескриптором exttags.tld. Мы не будем здесь останавливаться на правилах написания дескриптора библиотеки, а рассмотрим лишь один из возможных примеров его реализации:

1.0 1.2 dscat pageheader ru.view.tag.PageHeader

Создание библиотеки custom тэгов

Custom тэги без обработки содержимого

Программный код для поддержки custom тэга — это специальным образом написанный экземпляр Java класса, который вызывается web контейнером всякий раз, когда требуется обработать JSP страницу, содержащую соответствующий тэг.

В простейшем случае, для поддержки custom тэга можно взять какой-либо из классов бизнес-приложения и дополнить его методами, соответствующими интерфейсу Tag. Если же внешних объектов использовать не надо, то в качестве базового класса можно использовать TagSupport. Эти и другие стандартные классы и интерфейсы находятся в пакете javax.servlet.jsp.tagext.

Пример класса, осуществляющего поддержку custom тэга:

public CopyrightTag extends TagSupport { public int doStartTag() throws Exception { pageContext.getOut().print("© Copyright, 2001"); return SKIP_BODY; } public int doEndTag() { return EVAL_PAGE; } }

Методы класса, который осуществляет обработку custom тэга, вызываются в определенной последовательности. Когда в JSP странице обработка доходит до открывающего custom тэга, для его обработки вызывается метод doStartTag(). Когда обработка доходит до соответствующего закрывающего тэга, вызывается метод doEndTag(). Для обработки той части JSP страницы, которая заключена между этими двумя тэгами, используются методы doInitBody() и doAfterBody().

Помимо того, что метод doStartTag() может осуществлять какую-либо обработку запроса, большое значение имеет возвращаемое им значение. Если это SKIP_BODY, то информация, заключенная между соответствующими открывающим и закрывающим тэгами, будет игнорироваться, а обработка JSP страницы сразу перейдет на закрывающий тэг. Чтобы содержимое custom тэга все же обрабатывалось, медот должен возвратить EVAL_BODY_INCLUDE. Аналогично, если метод doEndTag() возвратит значение SKIP_PAGE, то оставшаяся часть JSP страницы после закрывающего тэга будет проигнорирована. Чтобы не допустить этого, метод должен возвратить значение EVAL_PAGE.

В некоторых случаях бывает необходимо показать содержимое custom тэга не один, а несколько раз. В этом случае, класс, осуществляющий обработку тэга, должен реализовывать интерфейс IterationTag, либо использовать в качестве родителя класс TagSupport. Чтобы повторить вывод содержимого custom тэга еще раз, необходимо, чтобы методы doStartTag и doAfterBody возвращали EVAL_BODY_AGAIN.

Custom тэги с обработкой содержимого

Если требуется доступ к содержимому custom тэга, то соответствующий Java класс должен реализовывать интерфейс BodyTag или же наследовать класс BodyTagSupport. И в том, и в другом случае класс может реализовать методы doInitBody и doAfterBody.

Метод doInitBody вызывается сразу после того, как выявлено содержимое тэга, но до того, как оно будет обработано. Обычно этот метод используется когда необходимо выполнить инициализацию класса в зависимости от содержимого custom тэга.

Метод doAfterBody вызывается после того, как содержимое custom тэга было обработано. Как и в предыдущем разделе, метод doAfterBody может указывать, следует ли повторить обработку содержимого тэга еще раз. Если это необходимо, метод должен возвратить значение EVAL_BODY_BUFFERED. В противном случае он должен возвратить SKIP_BODY.

В дополнение к двум предыдущим, технологией JSP предусмотрен вызов метода release с тем, чтобы позволить классу, осуществляющему поддержку custom тэга, освободить выделенные ему ресурсы, а также произвести другие необходимые действия для возврата в исходное состояние.

Непосредственно для доступа к содержимому custom тэга технологией предусмотрено два метода: getString и getReader.

Атрибуты в custom тэгах

Помимо информации в промежутке между открывающим и закрывающим тэгами, custom тэг может иметь некоторые атрибуты, которые также могут оказывать влияние на порядок обработки запроса клиента. Для каждого из таких атрибутов в классе, реализующем custom тэг, должен быть указан соответствующий атрибут, а также два метода get и set. Например, если custom тэг имеет вид

то реализующий этот custom тэг класс должен содержать следующий код:

из

Хорошо Плохо

Как вы уже знаете, C++ позволяет вам с помощью параметров передавать информацию в функции. Из урока 13 вы выяснили, что C++ также обеспечивает перегрузку функций, предусматривая определения, содержащие разное количество параметров или даже параметры разных типов. Кроме этого, в C++ при вызове функций можно опускать параметры. В таких случаях для опущенных параметров будут использоваться значения по умолчанию. Этот урок описывает как устанавливать значения по умолчанию для параметров функций. К концу данного урока вы освоите следующие основные концепции:

C++ позволяет программам указывать для параметров значения по умолчанию.

Значения по умолчанию для параметров указываются в заголовке функции при ее определении.

Если вызов функции опускает значения одного или нескольких параметров, C++ будет использовать значения по умолчанию.

Если вызов функции опускает значение определенного параметра, то должны быть опущены и значения всех последующих параметров.

Обеспечение значений по умолчанию для параметров упрощает возможность повторного использования функций (их использования несколькими программами).

ОПРЕДЕЛЕНИЕ ЗНАЧЕНИЙ ПО УМОЛЧАНИЮ

Обеспечить значения по умолчанию для параметров функции очень легко. Вы просто присваиваете значение параметру с помощью оператора присваивания С++ прямо при объявлении функции, как показано ниже:

void some_function(int size=12, float cost=19.95) //—->Значения по умолчанию

{
// Операторы функции
}

Следующая программа DEFAULTS. CPP присваивает значения по умолчанию параметрам a, b и c внутри функции show_parameters. Затем программа четыре раза вызывает эту функцию, сначала не указывая параметров вообще, затем указывая значение только для а, потом значения для а и b и, наконец, указывая значения для всех трех параметров:

#include

void show__parameters (int a=1, int b=2, int c=3)

{
cout << «a» << a << » b » << b << » с » << с << endl;
}

{
show_parameters();
show_parameters(1001);
show_parameters(1001, 2002);
show_parameters(1001, 2002, 3003);
}

Когда вы откомпилируете и запустите эту программу, на вашем экране появится следующий вывод:

С:\> DEFAULTS

а 1001 b 2 с 3

а 1001 b 2002 с 3

а 1001 b 2002 с 3003

Как видите, если необходимо, функция использует значения параметров по умолчанию.

Правила для пропуска значений параметров

Если программа опускает определенный параметр для функции, обеспечивающей значения по умолчанию, то следует опустить и все последующие параметры. Другими словами, вы не можете опускать средний параметр. В случае предыдущей программы, если требовалось опустить значение параметра b в show_parameters, программа также должна была опустить значение параметра с. Вы не можете указать значение для а и с, опуская значение Ь.

Задание значений по умолчанию

Когда вы определяете функцию, C++ позволяет вам указать значения по умолчанию для одного или нескольких параметров. Если программа в дальнейших вызовах этой функции опускает один или несколько параметров, то функция будет использовать для них значения по умолчанию. Чтобы присвоить параметру значение по умолчанию, просто используйте оператор присваивания внутри определения функции.
Например, следующая функция payroll указывает значения по умолчанию для параметров hours и rate:

float payroll(int employ_id, float hours = 40, float rate = 5.50)

// операторы
}

Когда программа опускает один параметр, она должна опускать все последующие параметры.

ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ

Из данного урока вы узнали, что C++ позволяет вам указывать значения по умолчанию для параметров функции. Если программа опускает один или несколько параметров, функция использует значения по умолчанию. В следующих уроках, когда ваши программы начнут использовать объектно-ориентированное программирование на C++, вы будете применять параметры по умолчанию для инициализации различных переменных класса. Как вы уже знаете, переменная позволяет вам хранить значение определенного типа (int, float и. т. д). В уроке 16 вы освоите, как хранить несколько значений одного и того же типа внутри массива.Например, ваша программа может хранить тестовые очки для 100 студентов или стоимость 50 акций. С помощью массивов хранить и использовать такие значения очень легко. До изучения урока 16 убедитесь, что вы освоили следующие основные концепции:

  1. Чтобы присвоить значения по умолчанию параметрам функции, используйте оператор присваивания C++ непосредственно в определении функции.
  2. Если программа опускает значения параметров при вызове функции, функция использует значения по умолчанию.
  3. Если программа опускает значение одного параметра, она должна опустить значения для всех последующих параметров; программа не может опускать средний параметр.
  4. Указывая параметры по умолчанию, вы тем самым облегчаете использование ваших функций, в том числе и для других программ.

В данной статье речь пойдет о процедурах и функциях. Она ориентирована в первую очередь на начинающих программистов, которые хотят лучше узнать все их возможности и научиться использовать их более эффективно. Однако и всем остальным эта статья может показаться полезной. Начнем.

В рамках статьи мы рассмотрим следующие вопросы:
Скобки

Добавление скобок при вызове процедур и функций без параметров уже давно не является новинкой в Delphi, тем не менее, эта возможность мало известна. Эту возможность оценят по достоинству те программисты, которым приходится работать на двух языках (C++ и Delphi), так как им не нужно будет постоянно помнить о разнице в синтаксисе при вызове процедур и функций в разных языках. В Delphi оба варианта, приведенные ниже, считаются корректными.

При вызове процедуры Test, Delphi сама решит, какую из трех процедур необходимо выполнить, в зависимости от передаваемого ей параметра. Но нужно отметить, что это не самая безопасная возможность языка. Применение перегружаемых процедур и функций может стать неиссякаемым источником трудноуловимых ошибок в программе. Поэтому пользуйтесь этой возможностью осторожно.

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

Этот режим передачи параметров применяется по умолчанию. Если параметр передается по значению, создается локальная копия данной переменной, которая и предоставляется для обработки в процедуру или функцию. Посмотрите на следующий пример:

procedure Test(s: string);

При вызове указанной процедуры будет создана копия передаваемой ей в качестве параметра строки s, с которой и будет работать процедура Test. При этом все внесенные в строку изменения никак не отразятся на исходной переменной s.

Однако это не относится к объектам. Например, если в функцию передается переменная (а точнее экземпляр объекта) TStringList, то в данном случае произойдет передача по ссылке (даже если это не указано явно).

Pascal позволяет также передавать параметры в функции или процедуры по ссылке - такие параметры называются параметрами-переменными. Передача параметра по ссылке означает, что функция или процедура сможет изменить полученные значения параметров. Для передачи параметров по ссылке используется ключевое слово var , помещаемое в список параметров вызываемой процедуры или функции.

Передача открытых массивов

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

Для получения информации о фактически передаваемом массиве параметров в функции или процедуре могут использоваться функции High, Low и SizeOf. Для иллюстрации их использования ниже приведен текст функции AddEmUp, которая возвращает сумму всех переданных ей элементов массива A.

Вызвать объявленную выше функцию можно, например, с помощью такого оператора:

procedure WhatHaveIGot(["Text", 10, 5.5, @WhatHaveIGot, 3.14, true, "c"]);

При передаче функции или процедуре массива констант все передаваемые параметры компилятор неявно конвертирует в тип TVarRec. Тип данных TVarRec объявлен в модуле System следующим образом:

Поскольку массив констант способен передавать данные разных типов, это может вызвать определенные затруднения при создании обрабатывающей полученные параметры функции или процедуры. В качестве примера работы с таким массивом рассмотрим реализацию процедуры WhatHaveIGot, которая просматривает элементы полученного массива параметров и выводит их тип.

procedure WhatHaveIGot(A: array of const); var i: integer; TypeStr: string; begin for i:= Low(A) to High(A) do begin case A[i].VType of vtInteger: TypeStr:= "Integer"; vtBoolean: TypeStr:= "Boolean"; vtChar: TypeStr:= "Char"; vtExtended: TypeStr:= "Extended"; vtString: TypeStr:= "String"; vtPointer: TypeStr:= "Pointer"; vtPChar: TypeStr:= "PChar"; vtObject: TypeStr:= "Object"; vtClass: TypeStr:= "Class"; vtWideChar: TypeStr:= "WideChar"; vtPWideChar: TypeStr:= "PWideChar"; vtAnsiString: TypeStr:= "AnsiString"; vtCurrency: TypeStr:= "Currency"; vtVariant: TypeStr:= "Variant"; vtInterface: TypeStr:= "Interface"; vtWideString: TypeStr:= "WideString"; vtInt64: TypeStr:= "Int64"; end; ShowMessage(Format("Array item %d is a %s", )); end; end;

Значения параметров по умолчанию

В Delphi есть одна очень полезная возможность - использование значений параметров по умолчанию. Она позволяет установить принимаемое по умолчанию значение параметра процедуры или функции. Это значение будет использоваться в тех случаях, когда вызов процедуры или функции производится без указания значения данного параметра. В объявлении процедуры или функции принимаемое по умолчанию значение параметра указывается после знака равенства, следующего после его имени. Поясним это на следующем примере:

Во втором случае можно задать только значение параметра s, а для параметра i использовать значение, установленное по умолчанию:

procedure HasDefVal("Hello");

При использовании значении параметров по умолчанию следует помнить о нескольких приведенных ниже правилах.
  • Параметры, имеющие значения по умолчанию, должны располагаться в конце списка параметров. Параметр без значения по умолчанию не должен встречаться в списке после параметра, имеющего значение по умолчанию.
  • Значения по умолчанию могут присваиваться только параметрам обычных типов, указателям или множествам.
  • Значение по умолчанию может передаваться только по значению либо с модификатором const . Оно не может быть ссылкой или нетипизированным параметром.
Одним из важных преимуществ применения значений параметров по умолчанию является простота расширения функциональных возможностей уже имеющихся процедур и функции с соблюдением обратной совместимости. Предположим, на рынок программных продуктов была выпущена программа, ключевым звеном которой является функция сложения двух целых величин:

Директива {$X-}

Директива {$X-} запрещает вызов функций как процедур (с игнорированием возвращаемого результата). По умолчанию этот режим включен ({$X+}). Так вот, запомните, использование переменной Result недопустимо при сброшенном флажке опции Extended Syntax, расположенном во вкладке Compiler диалогового окна Project Options, или при указании директивы компилятора {$X-} .

В каждой функции языка Objecl Pascal существует локальная переменная с именем Result, предназначенная для размещения возвращаемого значения. Кроме того, вернуть значение из функции можно также путем присвоения значения переменной, имеющей то же имя, что и данная функция. Это стандартный синтаксис языка Pascal, сохранившийся от его предыдущих версий. При использовании в теле функции переменной с ее именем не забывайте, что существуют большие отличия в обработке этого имени - все зависит от того, где она расположена - в левой части оператора присвоения или же в любом другом месте текста функции. Если имя функции указано в левой части оператора присвоения, то предполагается, что назначается возвращаемое функцией значение. Во всех других случаях предполагается, что осуществляется рекурсивный вызов этой функции.

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



Загрузка...