Статьи

Файлы JSP — части с 1 по 8: с метками и в мешках

Добро пожаловать в файлы JSP!

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

И если вам нужна небольшая помощь для начала работы, не забудьте дать Кевину Янку краткое руководство по JSP для Windows .

Файлы JSP — Часть 1. Фиолетовые свиньи в корзине с фруктами
Начните знакомство с Java Server Pages с помощью этого вводного руководства, которое охватывает переменные, включает в себя и объект String.

Файлы JSP — Часть 2: Атака Печенья Удачи Убийцы
Условные выражения, логические операторы и операторы сравнения, а также корзина, полная фортуны. О чем еще ты можешь попросить?

Файлы JSP — Часть 3: Черный Свет И Белые Кролики
Дополнительные методы объекта String и обзор различных управляющих структур, доступных в JSP.

Файлы JSP — Часть 4: Красная Таблетка
Узнайте, JSP может использоваться для обработки данных формы, и узнать об объекте запроса.

Файлы JSP. Часть 5. Адрес пересылки отсутствует
Создавайте динамические управляемые данными веб-страницы с помощью JSP.

Файлы JSP — Часть 6: Состояние Благодати
Узнайте, как «поддерживать состояние» на веб-сайте на основе JSP с помощью объектов Cookie и Session.

Файлы JSP — Часть 7: Ошибки, Бобы И Банки
Раздавите жуков, нагрейте бобы и узнайте немного больше о JSP.

Файлы JSP — часть 8: с метками и в мешках
Узнайте, как ускорить разработку кода JSP с помощью пользовательских библиотек тегов.

Наслаждайтесь!

Файлы JSP — Часть 1. Фиолетовые свиньи в корзине с фруктами

История JSP

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

Теперь мы большие поклонники Java — мы использовали его в прошлом и сделаем это снова в будущем — но эта серия руководств не о Java. На самом деле речь идет об ответвлении Java, безобидно названных Java Server Pages или JSP, которое пытается предложить веб-разработчикам убедительную альтернативу традиционным языкам сценариев на стороне сервера, таким как Perl, PHP и ASP.

Как? Сначала немного истории…

В первые дни Интернета, это было огромное количество (бесплатного!) Контента, который побуждал людей использовать его. Используя простой в освоении язык HTML, любой и их глухая бабушка могут создать веб-страницу и обратиться к другим единомышленникам в Интернете. По мере улучшения инфраструктуры контент больше не ограничивался текстом; Теперь вы можете просматривать фотографии или смотреть видео в Интернете. И по мере того, как все больше и больше людей начали добавлять интерактивность на свои веб-сайты, родилось множество языков программирования для удовлетворения все более сложных требований.

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

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

Однако у сервлетов есть собственная проблема — простая модификация интерфейса или логики часто может привести к далеко идущим изменениям сервлета. Итак, JSP был разработан для отделения логики приложения от интерфейса, чтобы изменения одного не влияли на другой. Работая в тесном сотрудничестве с разработчиками, такими как Apache Group, JSP использует основанный на тегах подход (аналог PHP и ASP), который позволяет дизайнерам вносить изменения в пользовательский интерфейс, не затрагивая логику приложения.

Если вас интересует масштабируемость, JSP поддерживает архитектуры на основе компонентов с использованием JavaBeans или Enterprise JavaBeans; это позволяет разработчику создавать повторно используемые модули кода и тем самым ускорить время разработки. А поскольку это Java, вы можете беспрепятственно подключать веб-приложения к унаследованным системам, тем самым снижая затраты на перенос реального бизнеса в киберпространство. Скажи это нам — платформа независимости качается!

Изучение Основ

JSP основан на многоуровневой архитектуре, которую лучше всего объяснить, сравнив ее с архитектурой, наблюдаемой на сайтах, отличных от JSP (читай: сайты на PHP или ASP). В типичной архитектуре Apache / PHP / mySQL у вас есть веб-сервер и сервер базы данных на одном уровне, а язык сценариев, такой как PHP, заботится о связи между ними для создания динамического контента. Хотя этот тип архитектуры подходит для сайтов, которые привлекают средний объем трафика, он начинает отображать свои бородавки при увеличении трафика и увеличении нагрузки на базу данных и веб-серверы.

С другой стороны, архитектура JSP включает в себя более одного уровня, что сразу делает его более масштабируемым и обслуживаемым.

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

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

Здесь важно отметить, что код JSP не читается построчно, как в PHP; сначала он преобразуется в сервлет (версия программы с байт-кодом), а затем вызывается механизмом сервлетов (например, Tomcat) для выполнения необходимых действий. Как только сервлет выполнен, результаты отправляются обратно клиенту. Поскольку движок сервлета должен компилировать сервлет в первый раз, отображение страницы JSP может занять некоторое время при первом обращении к ней; однако в следующий раз время отклика будет значительно сокращено, поскольку сервлет уже скомпилирован и поэтому готов к немедленному использованию.
Copyright Melonfire , 2000. Все права защищены.

Ява в стакане воды

Чтобы начать работу над JSP, вам необходимо получить копии Sun Java Development Kit, модуля веб-сервера Apache httpd и модуля mod_jserv, а также механизма сервлетов Tomcat и настроить их так, чтобы они работали вместе. В этом руководстве предполагается, что у вас настроена среда разработки JSP — если вы этого не сделаете, взгляните на учебник «Соединение среды разработки JSP» , который проведет вас через весь процесс.

После этого давайте перейдем к мелочам создания страницы JSP. Откройте новый файл в вашем любимом текстовом редакторе и введите следующие строки кода:

<html>  <head>  </head>  <body>  <%  // asking for it!   out.println("Waiter, can I have a cup of Java, please?");   %>  </body>  </html> 

Сохраните этот файл с расширением .jsp — например, «coffee.jsp» — в соответствующем месте, а затем просмотрите его, указав на него свой браузер — например, http: //localhost/jsp/coffee.jsp. Вы должны увидеть что-то вроде этого:

 <html>  <head>  </head>  <body>   Waiter, can I have a cup of Java, please?   </body>  </html> 

И это, кузнечик, ваш первый скриптлет!

В JSP-lingo «скриптлет» — это блок кода, выполняемый механизмом JSP, когда пользователь запрашивает страницу JSP. Все скриптлеты заключены в теги <%…%> (аналогично коду ASP и PHP), например:

 <%  ... JSP code ...   out.println("Waiter, can I have a cup of Java, please?");   ... JSP code ...  %> 

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

 Error: 500  Location: /jsp/coffee.jsp  Internal Servlet Error:  org.apache.jasper.JasperException: Unable to compile class:  Invalid type expression.  out.println("Waiter, can I have a cup of Java, please?")  ^  : Invalid declaration.  out.write("rnrnrn");  ^  2 errors  at org.apache.jasper.compiler.Compiler.compile  (Compiler.java, Compiled Code)  at org.apache.jasper.servlet.JspServlet.doLoadJSP  (JspServlet.java:462)  at  org.apache.jasper.servlet.JasperLoader12.loadJSP  (JasperLoader12.java:146)  at org.apache.jasper.servlet.JspServlet.loadJSP  (JspServlet.java:433)  at org.apache.jasper.servlet.JspServlet$JspServletWrapper.  loadIfNecessary(JspServlet.java:152)  at org.apache.jasper.servlet.JspServlet$JspServletWrapper.  service(JspServlet.java:164)  at org.apache.jasper.servlet.JspServlet.serviceJspFile  (JspServlet.java:318)  at org.apache.jasper.servlet.JspServlet.service  (JspServlet.java, CompiledCode)  at  javax.servlet.http.HttpServlet.service(HttpServlet.java:853)  at org.apache.tomcat.core.ServletWrapper.doService  (ServletWrapper.java:404)  at org.apache.tomcat.core.Handler.service(Handler.java:286)  at org.apache.tomcat.core.ServletWrapper.service  (ServletWrapper.java:372)  at org.apache.tomcat.core.ContextManager.internalService  (ContextManager.java:797)  at org.apache.tomcat.core.ContextManager.service  (ContextManager.java:743)  at org.apache.tomcat.service.connector.Ajp12Connection  Handler.processConnection(Ajp12ConnectionHandler.java:166)  at org.apache.tomcat.service.TcpWorkerThread.runIt  (PoolTcpEndpoint.java, Compiled Code)  at org.apache.tomcat.util.ThreadPool$ControlRunnable.run  (ThreadPool.java, Compiled Code)  at java.lang.Thread.run(Thread.java, Compiled Code) 

Упс!

Также возможно добавить комментарии к вашему коду JSP, как в примере выше. JSP поддерживает как однострочные, так и многострочные блоки комментариев — взгляните:

 <%   // this is a single-line comment  /* and this is a  multi-line  comment */   %> 

Как и PHP и Perl, пробел игнорируется в JSP.

Наконец, оператор, который фактически выводит вывод в браузер — как вы увидите, это делается с использованием объекта out. Поскольку JSP основан на Java, а Java — объектно-ориентированный язык, большинство ваших операторов JSP будут включать ссылки на объекты, такие как этот.
Copyright Melonfire , 2000. Все права защищены.

Введите Джон Доу

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

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

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

Например, «popeye», «one_two_three» и «bigPirateShip» являются допустимыми именами переменных, а «byte» и «123» являются недопустимыми именами переменных.

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

 <html>  <head>  </head>  <body>  <%!  // define variables here  String name = "John Doe";  %>   <%  // code comes here  out.println("My name is " + name );  %>  </body>  </html> 

Как видите, мы сначала определили переменную с именем «name», настроили ее так, чтобы она содержала строку или символ, данные, и присвоили ей значение («John Doe»). Это значение затем используется функцией println () для отображения сообщения на странице HTML.

 My name is John Doe 

Если у вас острые глаза, вы заметите небольшую разницу между двумя блоками JSP в примере выше — первый выглядит так:

 <%!  ...  %> 

… а второй выглядит так:

 <%  ...  %> 

Первый блок, в котором определены переменные, называется «блок объявления»; переменные, объявленные в этом блоке, доступны глобально для каждого сценария в этом документе JSP.

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

 <%  String name;  name = "John Doe";  %>   <%  String name = "John Doe";  %> 
Соединяя два и два вместе

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

  • int — используется для хранения целых чисел
  • char — используется для хранения одного символа в формате Unicode
  • float и long — используется для хранения чисел с плавающей точкой
  • логический — используется для хранения значений «истина» и «ложь» (обратите внимание, что в отличие от языков, таких как C и PHP, JSP не распознает 1 => истина и 0 => ложь)

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

 <html>  <head>  </head>  <body>  <%!  int alpha = 45;  int beta = 34;  int Sum;  %>  <%  // add the two numbers  Sum = alpha + beta;   // display the result  out.println("The sum of " + alpha + " and " + beta + " is " + Sum); %>  </body>  </html> 

И вывод:

 The sum of 45 and 34 is 79 

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

Аналогичным образом, следующий пример демонстрирует добавление строк вместе:

 <html>  <head>  </head>  <body>  <%!  // define the variables  String apples = "The lion ";  String oranges = "roars in anger";  String fruitBasket;  %>  <%  // print the first two strings  out.println("<b>The first string is</b>:  " + apples + "<br>"); out.println("<b>The second string  is</b>: " + oranges + "<br>");   // concatentate the strings  fruitBasket = apples + oranges;   // display  out.println("<b>And the combination is</b>: " + fruitBasket + "<br>Who  says you can't add apples and oranges?!");  %> </body> </html> 

И вывод:

 The first string is: The lion  The second string is: roars in anger  And the combination is: The lion roars in anger  Who says you can't add apples and oranges?! 

В этом случае оператор + используется для объединения двух строк, что затем отображается через println() .
Copyright Melonfire , 2000. Все права защищены.

Корзина

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

Первым из них является метод length() , используемый для получения (как вы уже догадались!) Длины конкретной строки. Давайте изменим пример, который вы только что видели, чтобы продемонстрировать, как это работает:

 <html>  <head>  </head>  <body>  <%!  // define the variables  String apples = "Purple pigs ";  String oranges = "riding orange pumpkins";  String fruitBasket;  %>  <%  // print the first two strings  out.println("<b>The first string is</b>: " + apples + "<br>"); out.println  ("<b>The second string is</b>: " + oranges + "<br>");   // concatentate the strings  fruitBasket = apples + oranges;   // display  out.println("<b>And the combination is</b>: " + fruitBasket + "(" +  fruitBasket.length() + " characters)<br>Who says you can't add  apples and oranges?!"); %> </body> </html> 

И вывод:

 The first string is: Purple pigs   The second string is: riding orange pumpkins   And the combination is: Purple pigs riding orange pumpkins(34 characters)  Who says you can't add apples and oranges?! 

Вы можете извлечь определенный символ из строки с помощью charAt() , который принимает смещение в качестве параметра. Например, следующий фрагмент кода вернет символ «o»:

 <%  String name = "Bozo The Clown";  out.println(name.charAt(3));  %> 

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

Вы также можете извлечь сегмент строки с помощью метода substring (), который позволяет указать начальную и конечную точки извлекаемого сегмента строки. Посмотрите на это предложение и посмотрите, сможете ли вы найти скрытое сообщение внутри него:

 <%!  String me = "I am a highly-skilled and hardworking developer!"; %> 
Нет? Как насчет сейчас?
<%! String me = "I am a highly-skilled and hardworking developer!"; String message; %> <% message = me.substring(0,2) + me.substring(15,22) + me.substring(26,27) + me.substring(45,48); out.println(message); %>

И вот вывод:

 I killed her! 

Алфавитный суп для души

Если вы использовали C раньше, вы, вероятно, уже знакомы с директивой include, которая появляется в начале каждой программы на C. JSP поддерживает эквивалентную функцию include (), которая делает то же самое. Взгляните на этот простой пример:

 <html>  <head>  <title> Thought For The Day</title>  </head>  <body>   Thought For The Day:  <br>  <%@ include file="thought.html" %>   </body>  </html> 

[Thought.html]

 Ever wonder if illiterate people get the full effect of alphabet soup? 

В этом случае JSP автоматически прочитает содержимое файла «ideas.html» и отобразит составную страницу, которая выглядит следующим образом:

 <html>  <head>  <title>Thought For The Day</title>  </head>  <body>   Thought For The Day:  <br>  Ever wonder if illiterate people get the full effect of alphabet soup?   </body>  </html> 

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

 <html>  <head>  </head>   <body>   ...your HTML page...   <br>   <%@ include file="footer.html" %>   </body>  </html> 

где «footer.html» содержит:

 <font size=-1 face=Arial>This material copyright Melonfire, 2001.  All rights reserved.</font> 

Теперь этот нижний колонтитул будет отображаться на каждой странице, содержащей приведенный выше оператор include() и, если вам нужно изменить сообщение, вам нужно всего лишь отредактировать один файл с именем «footer.html»!

И это на этой неделе. Мы показали вам основные строительные блоки JSP, и в следующий раз мы будем использовать эти фундаментальные концепции для демонстрации структур управления JSP. Не пропустите!

Примечание. Все примеры в этой статье были протестированы на Linux / i586 с Tomcat 3.2 и JServ 1.1. Примеры являются только иллюстративными и не предназначены для производственной среды. YMMV!
Copyright Melonfire , 2000. Все права защищены.

Файлы JSP — Часть 2: Атака печенек-убийц

Overdrive

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

Убедитесь, что вы пристегнуты — это будет чертовски круто!

Добавление всего этого

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

В следующем примере демонстрируются важные арифметические операторы, доступные в JSP:

 <html>  <head>  </head>  <body>   <%!  // declare variables  int alpha = 25;  int beta = 5;  int sum, difference, product, quotient, remainder;  %>   <%  // perform operations  out.println("The sum of " + alpha + " and "  + beta + " is " + (alpha + beta) + "<br>");   out.println("The difference of " + alpha + " and "  + beta + " is " + (alpha - beta) + "<br>");   out.println("The product of " + alpha + " and "  + beta + " is " + (alpha *  beta) + "<br>");   out.println("The quotient after division of " + alpha  + " and " + beta + " is " + (alpha / beta) + "<br>");  out.println("The remainder after division of " + alpha  + " and " + beta + " is " + (alpha % beta) + "<br>"); %>   </body>  </html> 

И вот вывод:

 The sum of 25 and 5 is 30  The difference of 25 and 5 is 20  The product of 25 and 5 is 125  The quotient after division of 25 and 5 is 5  The remainder after division of 25 and 5 is 0 

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

 <%  out.println(10 + 2 * 4);  %> 

возвращает 18, а:

 <%  out.println((10 + 2) * 4);  %> 

возвращает 48.

В дополнение к этим операторам JSP поставляется с очень полезными операторами автоматического увеличения [++] и автоматического уменьшения [-], о которых вы многое узнаете в следующей статье. Оператор автоинкремента увеличивает значение переменной, к которой он применяется, на 1, а оператор автоинкремента делает обратное. Вот пример:

 <%!  int x = 99;  %>   <%  // x = 99  out.println("Before increment, x = " + x + "<br>");  x++;  // x = 100  out.println("After increment, x = " + x);  %> 

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

Предположим, x = 4 и y = 10

оператор Что это значит выражение Результат
== равно х == у Ложь
знак равно не равно х! = у Правда
> больше, чем х> у Ложь
меньше чем Икс Правда
> = Больше или равно х> = у Ложь
меньше или равно Икс Правда

Copyright Melonfire , 2000. Все права защищены.

Вкус месяца

И так же, как вы можете сравнивать числа, JSP также позволяет сравнивать строки с парой очень полезных методов объекта String.

Во-первых, метод equals () позволяет проверить, соответствует ли значение определенной строковой переменной другому. Следующий пример должен продемонстрировать это.

 <%  // define variables  String myFavourite = "chocolate";  String yourFavourite = "strawberry";   // compare strings  if (myFavourite.equals(yourFavourite))  {  out.println("A match made in heaven!");  }  else  {  out.println("Naw - try again!");  }  %> 

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

Если метод equals() не подходит, JSP предлагает вам выбор в виде метода compareTo() , который возвращает значение, указывающее, какая из двух строк больше. Взглянем:

 <%  // define variables  String alpha = "abcdef";  String beta = "zyxwvu";   // compare strings  out.println(alpha.compareTo(beta));  %> 

В этом случае, если значение переменной «beta» больше, чем значение переменной «alpha», метод compareTo() вернет отрицательное целое число; если все наоборот, сравнение вернет положительное целое число. И если две строки идентичны, сравнение вернет 0.

Кстати, сравнение основано как на первом символе строки, так и на количестве символов в строке. Одна строка считается «большей», чем другая, если числовое значение ее первого символа больше или если ее длина больше. В приведенном выше примере «z» имеет больший числовой код, чем «a», поэтому сравнение вернет отрицательное целое число. Но не верьте нам на слово — попробуйте сами и посмотрите!

Поднимая жару

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

Первая — и самая простая — процедура принятия решения — это выражение «если», которое выглядит так:

 if (condition)  {  do this!  } 

«Условие» здесь относится к условному выражению, которое оценивается как истинное или ложное. Например,

 if (hard drive crashes)  {  get down on knees and pray for redemption  } 

или, в JSP-жаргоне:

 <%  if (hdd == 0)  {  pray();  }  %> 

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

Вот простая программа, которая иллюстрирует основы выражения «если».

 <%!  // declare temperature variable  int temp = 50;  %>   <%  // check temperature and display output  if (temp > 30)  {  out.println("Man, it's hot out there!");  }  %> 

В этом случае переменная с именем «temp» была определена и инициализирована значением 50. Далее, оператор «if» был использован для проверки значения переменной «temp» и отображения сообщения, если оно превышает 30. Обратите внимание, что мы используем условный оператор «больше чем (>)» в условном выражении.

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

Так:

 a = 47; 

присваивает значение 47 переменной a, тогда как

 a == 47 

проверяет, равно ли значение а 47.
Copyright Melonfire , 2000. Все права защищены.

Сделай это, или еще …

В дополнение к оператору «if» JSP также предлагает оператор «if-else», который позволяет выполнять различные блоки кода в зависимости от того, оценивается ли выражение как true или false.

Структура оператора if-else выглядит следующим образом:

 if (condition)  {  do this!  }  else  {  do this!  } 

В этом случае, если условное выражение оценивается как ложное, все операторы в фигурных скобках блока else будут выполняться. Изменив пример выше, мы имеем:

 <%!  // declare temperature variable  int temp = 50;  %>   <%  // check temperature and display output  if (temp > 30)  {  out.println("Man, it's hot out there!");  }  else  {  out.println("Well, at least it isn't as hot as it could be!"); } %> 

В этом случае, если первое прошлое конструкции завершается неудачей (температура * не * больше 30), управление передается второй части — инструкции «else» — и вместо этого выполняется код в блоке «else». Вы можете проверить обе возможности, изменив значение переменной «temp» и просмотрев полученный результат в своем браузере.

Код резака печенья

Конструкция «if-else», безусловно, предлагает smidgen большую гибкость, чем базовая конструкция «if», но все же ограничивает вас только двумя возможными вариантами действий. Если ваш сценарий должен быть способен обрабатывать более двух возможностей, вам следует обратиться к конструкции «if-else if-else», которая представляет собой удачное сочетание двух конструкций, о которых вы только что читали.

 if (first condition is true)  {  do this!  }  else if (second condition is true)  {  do this!  }  else if (third condition is true)  {  do this!  }   ... and so on ...   else  {  do this!  } 

Посмотрите на это в действии:

 <%!  // declare temperature variable  int temp = 20;  %>   <%  // check temperature and display output  // what happens if temp is less than 25 degrees  if (temp >= 25)  {  out.println("Man, it's hot out there!");  }  // what happens if temp is between 25 and 10 degrees  else if (temp < 25 && temp > 10)  {  out.println("Great weather, huh?!");  }  // what happens if temp is less than ten degrees  else if (temp <= 10)  {  out.println("Man, it's freezing out there!");  }  // this is redundant, included for illustrative purposes  else  {  out.println("Huh? Somebody screwed up out there!");  }  %> 

В этом случае, в зависимости от значения переменной «temp», выполняется соответствующая ветвь кода, что позволяет писать сценарии, которые допускают множество возможностей.

Здесь следует отметить один важный момент: управление передается последовательным ветвям «если», только если предыдущее условие (условия) оказывается ложным. Или, на английском языке, когда определенное условное выражение выполнено, все последующие условные выражения игнорируются.

Вот еще один пример, использующий день недели, чтобы решить, какой файл cookie удачи отображать. Измените переменную «day», чтобы каждый раз видеть разные cookie.

 <%!  String day = "Monday";  String fortune;  %>  <%  // check day and set fortune  if (day.equals("Monday"))  {  fortune = "Adam met Eve and turned over a new leaf.";  }  else if (day.equals("Tuesday"))  {  fortune = "Always go to other people's funerals, otherwise  they won't come to yours."; } else if (day.equals("Wednesday"))  { fortune = "An unbreakable toy is useful for breaking other toys."; }  else if (day.equals("Thursday")) { fortune = "Be alert - the  world needs more lerts."; } else if (day.equals("Friday"))  { fortune = "Crime doesn't pay, but the hours are good."; }  else { fortune = "Sorry, closed on the weekend"; }  // print output out.println(fortune); %  > 
Copyright Melonfire , 2000. Все права защищены.
Обед в Милане

Если вы внимательно посмотрите на последний пример выше, вы заметите, что условное выражение

 (temp < 25 && temp > 10) 

немного отличается от тех, к которым вы привыкли. Это связано с тем, что JSP также позволяет объединять несколько условий в одно выражение с помощью животного, называемого «логический оператор».

Следующая таблица должна прояснить это.

Предположим, дельта = 12, гамма = 12 и омега = 9

оператор Что это значит пример Перевод Оценивает до
&& И дельта == гамма && дельта> омега дельта равна гамме и дельта больше, чем омега Правда
&& И дельта == гамма && дельта дельта равна гамме и дельта меньше омеги Ложь
|| ИЛИ дельта == гамма || дельта дельта равна гамма ИЛИ
дельта меньше омега
Правда
|| ИЛИ дельта> гамма || дельта дельта больше гамма ИЛИ
дельта меньше омега
Ложь
! НЕ ! дельта дельта не соответствует действительности Ложь

Итак, вместо чего-то такого ужасного, как это:

 <%  if (day == "Thursday")  {  if (time == "12")  {  if (place == "Italy")  {  lunch = "pasta";  }  }  }   %> 

у вас может быть что-то такое элегантное, как это:

 <%  if (day == "Thursday" && time == "12" && place == "Italy")  {  lunch = "pasta";  }   %> 
Переключение вещей вокруг

Наконец, JSP округляет свои условные выражения с помощью оператора «switch», который предлагает альтернативный метод передачи управления из одного блока программы в другой. Вот как это выглядит:

 switch (decision-variable)  {  case first_condition_is true:  do this!   case second_condition_is true:  do this!   case third_condition_is true:  do this!   ... and so on...   default:  do this by default!   } 

Оператор «switch» лучше всего можно продемонстрировать, переписав предыдущий пример, используя «switch» вместо «if-else if-else».

 <%!  int dayOfWeek = 3;  String fortune;  %>  <%  // the decision variable here is the day chosen by the  user switch (dayOfWeek)  {   // first case  case 1:  fortune = "Adam met Eve and turned over a new leaf.";  break;   // second case  case 2:  fortune = "Always go to other people's funerals, otherwise  they won't come to yours.";  break;   case 3:  fortune = "An unbreakable toy is useful for breaking other toys.";  break;   case 4:  fortune = "Be alert - the world needs more lerts.";  break;   case 5:  fortune = "Crime doesn't pay, but the hours are good.";  break;   // if none of them match...  default:  fortune = "Sorry, closed on the weekend";  break;   }  // print output  out.println(fortune);  %> 

Первое, что вы заметите, это то, что переменная «day» из предыдущего примера была преобразована в числовую переменную «dayOfWeek» — это потому, что конструкция «switch» работает только тогда, когда переменная принятия решения является целым числом.

Здесь также есть пара важных ключевых слов: ключевое слово «break» используется для выхода из блока оператора «switch» и немедленного перехода к строкам, следующим за ним, а ключевое слово «default» используется для выполнения набора по умолчанию: операторы, когда переменная, переданная «switch», не удовлетворяет ни одному из условий, перечисленных в блоке.

И это все. Теперь вы знаете достаточно об условных выражениях JSP, чтобы начать писать простые программы — так что попрактикуйтесь! И вернемся к следующей проблеме, когда мы будем говорить о циклах, демонстрировать другие методы объекта String и даже бегло взглянуть на новый объект Response.

Примечание. Все примеры в этой статье были протестированы на Linux / i586 с Tomcat 3.2 и JServ 1.1. Примеры являются только иллюстративными и не предназначены для производственной среды. YMMV!
Copyright Melonfire , 2000. Все права защищены.

Файлы JSP — Часть 3: Черный Свет И Белые Кролики

Отсчет

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

Прежде всего, петли.

Как вы, возможно, уже знаете, «цикл» — это программная конструкция, которая позволяет вам снова и снова выполнять набор операторов, пока не будет выполнено заранее определенное условие.

Самым базовым циклом, доступным в JSP, является цикл while, и он выглядит так:

 while (condition)  {  do this!  } 

Или, чтобы сделать концепцию более ясной,

 while (temperature is below freezing)  {  wear a sweater  } 

«Условие» здесь является стандартным условным выражением, которое оценивается как true или false. Итак, если бы мы написали приведенный выше пример в JSP, это выглядело бы так:

 while (temp <= 0)  {  sweater = true;  } 

Вот пример:

 <html>  <head>  </head>  <body>  <%!  int countdown=30;  %>  <%  while (countdown > 0)  {  out.println(countdown + "&nbsp;");  countdown--;  }  out.println("<b>Kaboom!</b>");  %>  </body>  </html> 

Здесь переменная countdown инициализируется значением 30, а цикл while используется для уменьшения значения переменной до достижения значения 0. Как только значение переменной равно 0, условное выражение оценивается как false, и строки, следующие за циклом, выполняются.

Вот вывод:

 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13  12 11 10 9 8 7 6 5 4 3 2 1 Kaboom! 
Делать больше с петлями

Есть одна оговорка с циклом «пока». Если условное выражение в первый раз оценивается как ложное, код в фигурных скобках никогда не будет выполнен. Если это не то, что вам нужно, взгляните на цикл «do-while», который пригодится в ситуациях, когда вам нужно выполнить набор операторов * хотя бы * один раз.

Вот как это выглядит:

 do  {  do this!  } while (condition) 

Например, следующие строки кода не будут генерировать никакого вывода, поскольку условное выражение в цикле while всегда будет оцениваться как false.

 <%  int bingo = 366;   while (bingo == 699)  {  out.println ("Bingo!");  break;  }  %> 

Однако конструкция цикла «do-while» такова, что операторы внутри цикла выполняются первыми, а условие, которое нужно проверить, проверяется после. Использование цикла «do-while» подразумевает, что код в фигурных скобках будет выполнен по крайней мере один раз — независимо от того, будет ли условное выражение оценено как истинное.

 <%  int bingo = 366;   do  {  out.println ("Bingo!");  break;  } while (bingo == 699);  %> 

Попробуйте сами и увидите разницу.
Copyright Melonfire , 2000. Все права защищены.

Заброшенный вывод

Циклы «while» и «do-while» продолжают повторяться до тех пор, пока указанное условное выражение остается истинным. Но часто возникает необходимость выполнения определенного набора операторов определенное количество раз — например, печать серии из тринадцати последовательных чисел или повторение определенного набора ячеек <TD> пять раз. В таких случаях умные программисты тянутся к циклу «for» …

Цикл for обычно выглядит так:

 for (initial value of counter; condition; update counter)  {  do this!  } 

Похоже на бред? Хорошо, подожди минутку … здесь «счетчик» — это переменная JSP, которая инициализируется числовым значением и отслеживает количество выполнений цикла. Перед каждым выполнением цикла проверяется «условие» — если оно оценивается как true, цикл будет выполняться еще раз, и счетчик будет соответствующим образом увеличен; если он оценивается как false, цикл будет прерван, и вместо него будут выполнены строки, следующие за ним.

А вот простой пример, который демонстрирует, как можно использовать этот цикл:

 <html>  <head>  <basefont face="Arial">  </head>   <body>  <center>Turning The Tables, JSP-Style!</center>  <br>  <%!  // define the number  int number = 7;  int x;  %>  <%  // use a for loop to calculate tables for that number  for (x=1; x<=15; x++)  {  out.println(number + " X " + x + " = " + (number*x) + "<br>");  }  %>   </body>  </html> 

И вот вывод:

 Turning The Tables, JSP-Style!   7 X 1 = 7  7 X 2 = 14  7 X 3 = 21  7 X 4 = 28  7 X 5 = 35  7 X 6 = 42  7 X 7 = 49  7 X 8 = 56  7 X 9 = 63  7 X 10 = 70  7 X 11 = 77  7 X 12 = 84  7 X 13 = 91  7 X 14 = 98  7 X 15 = 105 

Давайте рассмотрим это немного:

Сразу же определяется переменная, содержащая число, которое будет использоваться для таблицы умножения; мы использовали 7 здесь — вы можете использовать другой номер.

Затем был создан цикл for в котором переменная-счетчик представляет собой «x». Если вы посмотрите на первую строку цикла, вы увидите, что «x» был инициализирован в 1 и настроен на выполнение не более 15 раз.

Наконец, функция println() используется для получения указанного числа, умножения его на текущее значение счетчика и отображения результата на странице.

Звук ломающихся петель

При работе с циклами следует помнить о двух важных ключевых словах: «break» и «continue».

Ключевое слово «break» используется для выхода из цикла при возникновении непредвиденной ситуации. Хорошим примером этого является страшная ошибка «деление на ноль» — при делении одного числа на другое (которое продолжает уменьшаться), желательно проверить делитель и использовать оператор «break» для выхода из цикла, как только он становится равным нулю.

Как вы уже видели, ключевое слово «continue» используется для пропуска определенной итерации цикла и немедленного перехода к следующей итерации — это продемонстрировано в следующем примере:

 <%  int x;  for (x=1; x<=10; x++)  {  if (x == 7)  {  continue;  }  else  {  out.println(x + "&nbsp;");  }  }  %> 

В этом случае JSP напечатает строку чисел от 1 до 10 — однако, когда он достигнет значения 7, оператор «continue» заставит его пропустить эту конкретную итерацию и вернуться к началу цикла. Так что ваша строка чисел не будет включать в себя 7 — попробуйте и убедитесь сами.
<font size = 1 color = «# aaaaaa» face = «Verdana, Arial, Helvetica»> Авторское право <a href=»http://www.melonfire.com/»> Melonfire </a>, 2000 г. Все права защищены. . </ FONT>

Оплата Пайпер

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

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

 <%  // define variable  String storyName = "The Pied Piper Of Hamlin";   // find index  int i = storyName.indexOf("i");   // print index  out.println("The letter i first occurs at " + i + "  in the string " + storyName); %> 

вот что вы увидите:

 The letter i first occurs at 5 in the string The  Pied Piper Of Hamlin 

Да, первый символ обрабатывается как индекс 0, второй как индекс 1 и так далее. Эти программисты …

Противоположностью этому является функция lastIndexOf() , используемая для определения последнего вхождения символа или подстроки в большей строке. Взглянем:

 <%  // define variable  String storyName = "The Pied Piper Of Hamlin";   // find index  int i = storyName.lastIndexOf("Pi");   // print index  out.println("The string Pi last occurs at " + i + "  in the string " + storyName); %> 

И вывод:

 The string Pi last occurs at 9 in the string The  Pied Piper Of Hamlin 

Если символ или подстрока не найдены, функция вернет код ошибки -1.

Громко кричать

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

 <%  // define variable  String whatIWant = " gimme my space ";   // trim!  // returns "gimme my space"  whatIWant.trim();  %> 

Методы toUpperCase() и toLowerCase() пригодятся, чтобы изменить регистр строки.

 <%  // define variable  String someString = "don't SCREam, help is oN the WAy!";   // uppercase - returns "DON'T SCREAM, HELP IS ON THE WAY!"  someString.toUpperCase();   // lowercase - returns "don't scream, help is on the way!"  someString.toLowerCase(); %> 

Функции startsWith() и endsWith() используются, чтобы проверить, начинается или заканчивается ли строка указанным символом или последовательностью символов. Следующий пример должен ясно проиллюстрировать это.

 <%  // define variables  String alpha = "black light";  String beta = "white rabbit";  String prefix = "bl";  String suffix = "it";   // check each string for prefixes and suffixes   if (alpha.startsWith(prefix))  {  out.println("The string " + alpha + " starts with  " + prefix + "<br>"); }   if (beta.startsWith(prefix))  {  out.println("The string " + beta + " starts with  " + prefix + "<br>"); }   if (alpha.endsWith(suffix))  {  out.println("The string " + alpha + " ends with " +  suffix + "<br>"); }   if (beta.endsWith(suffix))  {  out.println("The string " + beta + " ends with " +  suffix + "<br>"); }   %> 

И вывод:

 The string black light starts with bl  The string white rabbit ends with it 

Copyright Melonfire , 2000. Все права защищены.

Вы говорите семь, я говорю 7

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

 <%  // converting a string to a number   // define variables  String someString = "97";  int aRandomNumber = 3;   // at this stage, someString is still treated as a string  out.println(someString + " plus " + aRandomNumber  + " equals " + (someString+aRandomNumber) + "<p>");   // now convert someString to a number  int someNumber  = Integer.parseInt(someString);   // at this stage, someString has been converted to a  number, stored in someNumber out.println(someNumber +  " plus " + aRandomNumber + " equals " + (someNumber+aRandomNumber));   %> 

И вот вывод.

 97 plus 3 equals 973  97 plus 3 equals 100 

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

 <%  // define variables  int someNumber = 97;  int aRandomNumber = 3;   // at this stage, someNumber is still treated as a number  out.println(someNumber + " plus " + aRandomNumber + "  equals " + (someNumber+aRandomNumber) + "<p>");   // now convert someNumber to a string  String someString = Integer.toString(someNumber);   // at this stage, someNumber has been converted to a  string, stored in someString out.println(someString +  " plus " + aRandomNumber + " equals " + (someString+aRandomNumber));   %> 

И вот вывод.

 97 plus 3 equals 100  97 plus 3 equals 973 

Результат? parseInt() и toString() — ваши лучшие друзья при преобразовании между строковыми и числовыми типами данных в JSP.

Положительный ответ

Другим интересным объектом, который пригодится в самых странных местах, является объект Response. В отличие от объекта Request, который используется для извлечения информации (зайдите в следующий раз, чтобы узнать об этом подробнее), объект Response обычно используется для отправки информации в браузер; эта информация может включать заголовки HTTP, URL-адреса перенаправления, файлы cookie и множество других элементов.

Поскольку объект Response является «неявным» объектом (так называемым, потому что вам не нужно явно создавать экземпляр объекта, когда вы хотите его использовать), вы можете сразу начать использовать его в документе JSP. В следующем примере демонстрируется использование его для отключения кэширования через заголовок «Cache-Control».

 <%  response.setHeader("Cache-Control","no-cache");  %>  [/code]  You can also use it to redirect the client to another URL.  

%
response.setHeader ("Location", "error.html");
%>

Вы можете использовать метод sendRedirect() для выполнения чего-то подобного - не забудьте использовать здесь абсолютный URL.

 <%  response.sendRedirect("http://my.server.com/error.html");  %> 

Вы можете установить MIME-тип документа с помощью setContentType() .

 <%  response.setContentType("image/jpeg");  %> 

и даже установить cookie с помощью addCookie() - подробнее об этом по мере продвижения по этой серии.

Это все, на что у нас есть время. В следующий раз мы будем исследовать объект JSP Response, используемый для обработки данных из HTML-форм ... так что вы не хотите пропустить это!

Примечание. Все примеры в этой статье были протестированы на Linux / i586 с Tomcat 3.2 и JServ 1.1. Примеры являются только иллюстративными и не предназначены для производственной среды. YMMV!
Copyright Melonfire , 2000. Все права защищены.


Файлы JSP - Часть 4: Красная Таблетка

Применяя Теорию

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

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

Последний герой действия

HTML-формы обычно используются для получения информации от посетителей веб-сайта - таких как их имя, почтовый адрес, номер телефона и т. Д. - и эта информация затем обрабатывается различными способами. Некоторые сайты хранят его в базе данных; другие отправляют это по электронной почте веб-мастеру; а другие просто перенаправляют его в корзину для мусора. Используя JSP для обработки формы, вы можете написать простые фрагменты кода, которые выполняют все эти действия.

Давайте начнем с простого примера.

 <html>   <head>  <basefont face="Arial">  </head>   <body>   <center>  <form method="GET" action="matrix.jsp">  <table cellspacing="5" cellpadding="5" border="0">   <tr>  <td>  <font size="-1">Name, rank and serial, number, soldier!</font>  </td> <td align="left"> <input type="text" name="name" size="10">  </td> </tr>    <tr>  <td colspan="2" align="center">  <input type="submit">  </td>  </tr>   </table>  </form>   </center>  </body>   </html> 

Наиболее важной строкой на всей этой странице является <form> :

 <form method="GET" action="matrix.jsp">   ...   </form> 

Как вы, вероятно, уже знаете, атрибут ACTION <FORM> указывает имя серверного сценария - в данном случае «matrix.jsp», который будет обрабатывать информацию, введенную в форму, в то время как атрибут METHOD указывает способ, которым информация будет передана.

Copyright Melonfire , 2000. Все права защищены.


Ввод матрицы

После отправки формы вызывается скрипт "matrix.jsp" для анализа даты, введенной в форму. На этом этапе сценарий просто читает имя, введенное в форму, и отображает сообщение, содержащее это имя; однако позже он будет изменен для предоставления или отказа в доступе на основе введенного имени.

 <html>  <head>  <basefont face="Arial">  </head>   <body>  <center>  <%  // matrix.jsp   // define the variables used in the scriptlet  String fname;   // assign values  fname = request.getParameter("name");   // print the details  out.println("Welcome to The Matrix, " + fname + "!");   %>  </center>  </body>  </html> 

И теперь, если вы введете некоторые данные в форму (скажем, «Джо»), это то, что вы должны увидеть:

 Welcome to The Matrix, joe! 

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

 <%  // define the variables used in the scriptlet  String fname;  %> 

Затем значение переменной формы « name » должно быть присвоено переменной JSP « fname » - это достигается с помощью getParameter() , который принимает имя переменной в качестве параметра и возвращает значение переменной.

Метод getParameter() фактически принадлежит объекту JSP, который называется объектом запроса; в отличие от многих других объектов в JSP, объект Request является «неявным» объектом, так называемым, потому что вам не нужно явно создавать экземпляр объекта, когда вы хотите его использовать. Метод getParameter() - это только один из многих методов, доступных в этом объекте, и мы рассмотрим некоторые другие в этом учебном пособии.

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

Вы также можете использовать метод POST (который обеспечивает большую безопасность и надежность) для обработки данных формы - просто измените HTML-форму так, чтобы использовался МЕТОД POST .

 <form method="POST" action="matrix.jsp">   ...   </form> 

Скрипт matrix.jsp будет продолжать работать так, как объявлено, без каких-либо изменений. Таким образом, метод getParameters() может использоваться для доступа к переменным формы независимо от метода, используемого для публикации данных.

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

 <html>  <head>  <basefont face="Arial">  </head>   <body>  <center>  <%  // matrix.jsp   // define the variables used in the scriptlet  String fname;   // assign values  fname = request.getParameter("name");   // print the details  if (fname.equals("neo"))  {  out.println("Welcome to The Matrix, Neo!");  }  else  {  out.println("Leave immediately, Agent!");  }  %>  </center>  </body>  </html> 

Copyright Melonfire , 2000. Все права защищены.


Запросить больше

Объект Request также поставляется с кучей других полезных методов - в следующем примере демонстрируются некоторые из них.

 <html>  <head>  <basefont face="Arial">  </head>  <body>   <table border="1" cellspacing="5" cellpadding="5">  <tr>  <td><b>Variable</b></td>  <td><b>Value</b></td>  </tr>   <tr>  <td>Request protocol</td>  <td>  <%  // protocol  out.println(request.getProtocol());  %>  </td>  </tr>   <tr>  <td>Hostname</td>  <td>  <%  // server name  out.println(request.getServerName());  %>  </td>  </tr>   <tr>  <td>Port</td>  <td>  <%  // server port  out.println(request.getServerPort());  %>  </td>  </tr>   <tr>  <td>Remote username</td>  <td>  <%  // username if using HTTP authentication  // null if no authentication out.println(request.getRemoteUser());  %>  </td>  </tr>   <tr>  <td>Remote address</td>  <td>  <%  // get IP address of client out.println(request.getRemoteAddr());  %>  </td>  </tr>   <tr>  <td>Client browser</td>  <td>  <%  // client browser identification out.println  (request.getHeader("User-Agent"));  %>  </td>  </tr>   </table>  </body>  </html> 

И когда вы просматриваете файл в своем браузере, вы, вероятно, увидите что-то вроде этого:

 Variable    Value  Request protocol    HTTP/1.0  Hostname    localhost  Port      80  Remote username  null  Remote address    192.168.0.143  Client browser    Mozilla/4.0 (compatible; MSIE 5.5; Windows 95) 

Все эти переменные пригодятся, если вам нужно принимать решения на основе удаленных переменных - как показано в следующем примере:

 <%  String browser = request.getHeader("User-Agent");  if(browser.indexOf("MSIE") >= 0)  {  // IE-specific code  }  else if(browser.indexOf("Mozilla") >= 0)  {  // Mozilla-specific code  }  else  {  // any other browser  }  %> 

Обратите внимание на наше использование метода indexOf() - вы можете помнить это из предыдущих статей этой серии.

Copyright Melonfire , 2000. Все права защищены.


Принимая лекарства

Так же, как вы можете получить доступ к данным из текстовых полей, вы также можете использовать
getParameter() для оценки состояния переключателей и списков. Предположим, вы изменили форму выше на что-то более сложное.

 <html>   <head>  <basefont face="Arial">  </head>   <body>   <center>  <form method="GET" action="pills.jsp">   <font size="-1" face="Arial">  Gimme  <select name="quantity">  <option value="10">10</option>  <option value="25">25</option>  <option value="50">50</option>  <option value="100">100</option>  </select>  of those little  <input type="Radio" name="colour" value="red" checked>red  <input type="Radio" name="colour" value="blue">blue  pills, willya? </font>   <p>   <input type="Submit">  </form>   </center>  </body>   </html> 

А вот и «pills.jsp».

 <html>  <head>  <basefont face="Arial">  </head>   <body>  <center>  <%  // pills.jsp   // define the variables and assign values  String colour = request.getParameter("colour");  String quantity_string = request.getParameter("quantity");   // convert string to number  int quantity = Integer.parseInt(quantity_string);    // process and display   // who needs green pills?  if (colour.equals("blue"))  {  out.println("Sorry, we don't carry blue pills here.");  }  else  {  if (quantity >= 50)  {  out.println("Stocking up, are we?");  }  else  {  out.println("Here you go. And would you like fries with that?");  }  }  %>  </center>  </body>  </html> 

В зависимости от комбинации типа и количества таблеток будет отображаться соответствующее сообщение.

Как вы можете видеть, оценка переключателей и списков почти идентична оценке обычных текстовых полей.

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

Copyright Melonfire , 2000. Все права защищены.


Что на десерт?

Пока что используемые вами переменные содержат только одно значение - например,

 int i = 0 

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

 String[] desserts = {"chocolate mousse", "tiramisu",  "apple pie", "chocolate fudge cake"}; 

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

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

Доступ к различным элементам массива осуществляется через порядковый номер, причем первый элемент начинается с нуля. Итак, для доступа к элементу

 "chocolate mousse" 

вы бы использовали обозначение

 desserts[0] 

пока

 "chocolate fudge cake" 

было бы

 desserts[3] 

- по сути, имя переменной массива, за которым следует номер индекса, заключенный в квадратные скобки. Вундеркинды называют это «индексацией с нуля».

Определение переменной массива в JSP несколько запутанно по сравнению с такими языками, как PHP и Perl; вам нужно сначала объявить переменную и ее тип, а затем создать массив.

 <%  // declare type of array  String[] desserts;   // initialize array  // the number indicates the number of elements the array will  hold desserts = new String[4];   // assign values to array elements  desserts[0] = "chocolate mousse";  desserts[1] = "tiramisu";  desserts[2] = "apple pie";  desserts[3] = "chocolate fudge cake";  %> 

Или вы можете использовать более простую версию:

 <%  String[] desserts = {"chocolate mousse", "tiramisu",  "apple pie", "chocolate fudge cake"}; %> 

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

Шоколадная зависимость

Чтобы изменить элемент массива, вы просто должны присвоить новое значение соответствующей переменной. Если вы хотите заменить «шоколадный торт» на «шоколадное печенье», вы просто используете

 <%  desserts[3] = "chocolate chip cookies";  %> 

и массив теперь будет читать

 String[] desserts = {"chocolate mousse", "tiramisu",  "apple pie", "chocolate chip cookies"}; 

Массивы JSP могут хранить только тип данных, указанный во время объявления переменной массива; строковый массив не может содержать числа или наоборот.

И, наконец, вы можете получить количество элементов в массиве с помощью свойства length - следующий пример демонстрирует это:

 <html>  <head>  <basefont face="Arial">  </head>   <body>  <%  // define an array  String[] desserts = {"chocolate mousse", "tiramisu",  "apple pie", "chocolate fudge cake"};   // display array length  out.println("The dessert menu  contains " + desserts.length + " items.");  %>  </body> </html> 

И вывод:

 The dessert menu contains 4 items. 

Вы можете использовать цикл for для итерации элементов массива, как показано в следующем примере.

 <html>  <head>  <basefont face="Arial">  </head>   <body>  Desserts available:  <ul>   <%  // define counter  int counter;   // define an array  String[] desserts = {"chocolate mousse", "tiramisu",  "apple pie", "chocolate fudge cake"};   for (counter=0; counter<desserts.length; counter++)  {  out.println("<li>" + desserts[counter] + "<br>");  }  %>   </ul>  </body>  </html> 

И вывод:

 Desserts available:  · chocolate mousse  · tiramisu  · apple pie  · chocolate fudge cake 

Copyright Melonfire , 2000. Все права защищены.


Лежебока

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

 <html>  <head>  <basefont face="Arial">  </head>  <body>   Pick your favourite shows:  <br>  <form action="potato.jsp" method="POST">  <input type="checkbox" name="shows" value="Ally McBeal">Ally  McBeal <input type="checkbox" name="shows" value="Buffy The  Vampire Slayer">Buffy The Vampire Slayer <input type="checkbox"  name="shows" value="The Practice">The Practice <input  type="checkbox" name="shows" value="Sex And The City">Sex  And The City <input type="checkbox" name="shows"  value="The Sopranos">The Sopranos <input type="checkbox"  name="shows" value="Survivor">Survivor <br> <input type="submit"  name="submit" value="Select"> </form>   </body>  </html> 

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

 <html>  <head>  <basefont face="Arial">  </head>  <body>   So your favourite shows are:  <br>  <%   // potato.jsp - process list of selected TV shows   // define variables  String[] Shows;   // assign values to variables  Shows = request.getParameterValues("shows");   out.println("<ul>");   // print by iterating through array  for(int counter = 0; counter < Shows.length; counter++)  {  out.println("<li>" + Shows[counter]);  }   out.println("</ul>");  %>   </body>  </html> 

Как видите, первым делом стоит создать массив для хранения данных флажка - в данном случае массив «Показывает». Затем объект Request используется для получения значений выбранных элементов через
getParameterValues() (похож на метод getParameter() , но возвращает список значений, а не одно значение), и эти значения затем присваиваются массиву « Shows ». Затем используется цикл for для создания списка выбранных элементов.

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

 <html>  <head>  <basefont face="Arial">  </head>  <body>   Pick your favourite shows:  <br>  <form action="potato.jsp" method="POST">  <select name="shows" multiple>  <option>Ally McBeal</option>    <option>Buffy The Vampire Slayer</option>    <option>The Practice</option>    <option>Sex And The City</option>    <option>The Sopranos</option>    <option>Survivor</option>  </select>  <br>  <input type="submit" name="submit" value="Select">  </form>   </body>  </html> 

Очевидно, что серверный скрипт "potato.jsp" вообще не требует изменений.

Copyright Melonfire , 2000. Все права защищены.


Победить в подчинении

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

Вы уже видели, что после отправки формы в сценарий JSP все переменные формы становятся доступными для JSP. Теперь, в дополнение к пользовательским переменным, каждый раз, когда вы нажимаете кнопку SUBMIT на форме, создается переменная с именем « submit ». А проверяя наличие или отсутствие этой переменной, умный разработчик JSP может использовать один документ JSP для генерации как начальной формы, так и вывода после ее отправки.

Следующий фрагмент кода демонстрирует, как вышеприведенный пример «welcome to The Matrix» может быть переписан с использованием этой техники.

 <html>  <head>  <basefont face="Arial">  </head>   <body>  <center>  <%  // matrix.jsp   // check for submit variable  String submit = request.getParameter("submit");   if(submit != null)  {  // form has been submitted, display result   // define the variables used in the scriptlet  String fname;   f  // assign values  fname = request.getParameter("name");   // print the details  out.println("Welcome to The Matrix, " + fname + "!");   }  else  {  // display initial form  %>   <form method="GET" action="matrix.jsp">  <table cellspacing="5" cellpadding="5" border="0">   <tr>  <td>  <font size="-1">Name, rank and serial, number, soldier!</font>  </td> <td align="left"> <input type="text" name="name" size="10">  </td> </tr>   <tr>  <td colspan="2" align="center">  <input name="submit" type="submit">  </td>  </tr>   </table>  </form>   <%  }  %>  </center>  </body>  </html> 

Как видите, скрипт сначала проверяет наличие submitпеременной " " - если он не находит ее, он предполагает, что форма еще не отправлена, и поэтому отображает первоначальную форму.

Поскольку ACTIONатрибут <FORM>тега ссылается на тот же JSP-скрипт, после отправки формы будет вызываться тот же скрипт для обработки ввода формы. Однако на этот раз submitпеременная " " будет существовать, и поэтому JSP будет отображать не начальную страницу, а страницу результатов.

Обратите внимание, что для этого, ваш

 <input type="submit"> 

должен иметь NAMEатрибут со значением " submit", например так:

 <input type="submit" name="submit"> 

И это все. В следующий раз мы подключим JSP к базе данных, чтобы создать динамическую веб-страницу - так что не пропустите ее. До тех пор ... оставайся здоровым!

Примечание. Все примеры в этой статье были протестированы на Linux / i586 с Tomcat 3.2 и JServ 1.1. Примеры являются только иллюстративными и не предназначены для производственной среды. YMMV!
Copyright Melonfire , 2000. Все права защищены.


Файлы JSP - Часть 5: Нет адреса пересылки

Ящик для инструментов

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

Предлагая бесшовное подключение к базе данных (хорошо, оно не так прозрачно, как подключение к базе данных, доступное в PHP, но все же довольно хорошо!) В сочетании с более быстрым временем отклика, JSP позволяет разработчикам создавать сложные масштабируемые веб-приложения, управляемые данными, одновременно наслаждаться короткими циклами развития.

ОК, - сказал он. Давайте перейдем к преследованию.

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

Если вы планируете попробовать приведенные ниже примеры (рекомендуется), вам необходимо загрузить и установить сервер базы данных mySQL, доступный по адресу http://www.mysql.com/ . MySQL - это быстрая, надежная система управления базами данных с открытым исходным кодом, которая предлагает достаточное количество энергии по цене, которая должна вызвать у вас слезы - это бесплатно!

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

Поскольку все взаимодействие с базами данных в Java происходит с использованием технологии, известной как JDBC или Java Database Connectivity, вам также потребуется модуль JDBC, который позволяет подключаться к серверу базы данных mySQL. Предположим, что вы загрузили модуль mm.mySQL JDBC из раздела «Соединение среды разработки JSP» .

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

Наконец, некоторые знания SQL пригодятся. В случае, если вы не знаете SQL, не беспокойтесь - это очень просто, и через несколько минут с помощью учебника «Говорящий SQL» вы сможете выполнять запросы как эксперт.

Со всем этим, давайте на самом деле запачкаем руки.

Выброс!

Если вы знакомы с SQL, вы знаете, что с базой данных возможно четыре основных типа операций:

  • ВЫБЕРИТЕ запись;
  • ВСТАВИТЬ запись;
  • ОБНОВИТЬ запись;
  • УДАЛИТЬ запись.

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

Как всегда, одна из первых вещей, о которых вы должны подумать при разработке приложения, управляемого данными, - это проект базы данных (да!). Для этого приложения мы решили использовать одну таблицу с именем «abook», которая содержит поля для различных типов контактной информации - адреса, телефона, факса, адреса электронной почты и т. П. Каждый пользователь в системе имеет уникальный идентификатор входа, и каждая запись в базе данных «принадлежит» определенному пользователю.

Мы собрали «файл дампа», который позволяет быстро создавать таблицы базы данных и начальный набор записей - мы предлагаем импортировать эти данные на сервер базы данных mySQL, как мы будем использовать в этой статье.

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

 mysql> mysql -u username -p database < dumpfile 

Или вы можете вставить содержимое вручную - вот что вам нужно:

 #  # Table structure for table 'abook'  #   DROP TABLE IF EXISTS abook;  CREATE TABLE abook (   id int(11) unsigned NOT NULL auto_increment,   uid varchar(255) NOT NULL,   fname varchar(255) NOT NULL,   lname varchar(255) NOT NULL,   tel varchar(255),   fax varchar(255),   email varchar(255),   addr text,   company varchar(255),   comment text,   PRIMARY KEY (id)  );   #  # Dumping data for table 'abook'  #   INSERT INTO abook (id, uid, fname, lname, tel, fax, email,  addr, company,comment) VALUES ( '1', 'john', 'Bugs',  'Bunny', '7376222', '', '[email protected]', 'The Rabbit  Hole, Dark Woods, Somewhere On Planet Earth', '',  'Big-ears in da house!'); INSERT INTO abook (id, uid,  fname, lname, tel, fax, email, addr, company,  comment) VALUES ( '2', 'john', 'Elmer', 'Fudd', '', '7628739',  '[email protected]','', '', ''); INSERT INTO abook (id,  uid, fname, lname, tel, fax, email, addr, company,comment)  VALUES ( '3', 'joe', 'Peter', 'Parker', '162627 x34', '',  '[email protected]', 'Your Friendly Neighbourhood  Newspaper', '', 'My spidey-sense is tingling!');  INSERT INTO abook (id, uid, fname, lname, tel, fax, email,  addr, company, comment) VALUES ( '4', 'bill',  'Clark', 'Kent', '1-800-SUPERMAN', '',  '[email protected]', '', '', 'Is it a bird? Is  it a plane?'); 

Это создаст таблицу с именем " abook" со столбцами для различных типов контактной информации; Эти записи принадлежат трем мифическим пользователям: «Билл», «Джон» и «Джо».

Теперь проверьте, были ли данные успешно импортированы с помощью SELECTзапроса (оператор SELECT SQL используется для извлечения информации из базы данных). Введите это в командной строке mySQL:

 mysql> select uid, fname, lname from abook; 

что на английском языке означает «отображать столбцы uid, fname и lname из адресной книги». Вот что вы должны увидеть:
+------+-------+--------+ | uid | fname | lname | +------+-------+--------+ | john | Bugs | Bunny | | john | Elmer | Fudd | | joe | Peter | Parker | | bill | Clark | Kent | +------+-------+--------+ 4 rows in set (0.00 sec)
Copyright Melonfire , 2000. Все права защищены.

Живописный маршрут

Все работает? Хорошо. Теперь давайте использовать JSP для того же - запустить SELECTзапрос к базе данных и отобразить результаты на HTML-странице.

 <html>  <head>  <basefont face="Arial">  </head>  <body>  <%@ page language="java" import="java.sql.*" %>   <%!  // define variables  String UId;  String FName;  String LName;   // define database parameters  String host="localhost";  String user="us867";  String pass="jsf84d";  String db="db876";  String conn;  %>   <table border="2" cellspacing="2" cellpadding="5">   <tr>  <td><b>Owner</b></td>  <td><b>First name</b></td>  <td><b>Last name</b></td>  </tr>   <%   Class.forName("org.gjt.mm.mysql.Driver");   // create connection string  conn = "jdbc:mysql://" + host + "/" + db + "?user=" + user  + "&password=" + pass;   // pass database parameters to JDBC driver  Connection Conn = DriverManager.getConnection(conn);   // query statement  Statement SQLStatement = Conn.createStatement();   // generate query  String Query = "SELECT uid, fname, lname FROM abook";   // get result  ResultSet SQLResult = SQLStatement.executeQuery(Query);   while(SQLResult.next())  {    UId = SQLResult.getString("uid");    FName = SQLResult.getString("fname");    LName = SQLResult.getString("lname");     out.println("<tr><td>" + UId + "</td><td>" +  FName + "</td><td>" + LName + "</td></tr>");  }   // close connection  SQLResult.close();  SQLStatement.close();  Conn.close();   %>   </table>  </body>  </html> 

И вы увидите что-то вроде этого:
Owner First name Last name john Bugs Bunny john Elmer Fudd joe Peter Parker bill Clark Kent
Copyright Melonfire , 2000. Все права защищены.

Один шаг за раз

Использование JSP для извлечения данных из базы данных включает в себя несколько шагов. Давайте рассмотрим каждый из них.

1. Во-первых, нам нужно убедиться, что все модули, необходимые для соединения JDBC, доступны для документа JSP. Это достигается с помощью

 <%@ page  ...  %> 

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

 <%@ page language="java" import="java.sql.*" %> 

importАтрибут " " используется для импорта всех пакетов и классов, необходимых для выполнения скрипта - здесь все пакеты в java.sql.*дереве " ".

2. Далее необходимо объявить все переменные, необходимые для этого скриптлета; мы оставили некоторые из них для результатов запроса SQL, а также создали переменные для хранения информации, относящейся к базе данных, такой как имя сервера базы данных, имя пользователя и пароль, необходимые для получения доступа, и база данных, используемая для всех запросы. Эта информация используется для построения строки соединения на более позднем этапе.

3. Следующим шагом является загрузка драйвера JDBC, необходимого для доступа к базе данных mySQL - это выполняется с помощью инструкции

 Class.forName("org.gjt.mm.mysql.Driver"); 

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

4. Теперь, когда драйверы загружены, пришло время открыть соединение с сервером базы данных. Это достигается с помощью объекта Connection и его getConnection()метода.

getConnection()Метод требует строки соединения в качестве аргумента; эта строка подключения создается путем объединения имени сервера, имени пользователя и пароля и имени базы данных для использования в одну строку, похожую на URL.

 // create connection string  conn = "jdbc:mysql://" + host + "/" + db + "?user=" + user  + "&password=" + pass;   // pass database parameters to JDBC driver  Connection Conn = DriverManager.getConnection(conn); 

Затем getConnect()метод возвращает идентификатор соединения, который используется для последующих запросов SQL. Все взаимодействие между JSP и сервером базы данных происходит через это соединение. В этом случае конкретный экземпляр Connectionобъекта называется « Conn».

5. Как только соединение с базой данных становится доступным, Statementобъект используется для подготовки оператора SQL к выполнению.

 // query statement  Statement SQLStatement = Conn.createStatement(); 

6. На этом этапе создается запрос:

 // generate query  String Query = "SELECT uid, fname, lname FROM abook"; 

и ResultSetобъект используется для хранения результатов запроса.

 // get result  ResultSet SQLResult = SQLStatement.executeQuery(Query); 

7. Как только запрос выполнен и результаты возвращены, можно использовать несколько методов для итерации набора результатов. В приведенном выше примере используется next()метод, который просто перемещается по списку записей, возвращаемых запросом. Цикл " while" используется для итерации набора результатов в сочетании с next()методом.

 // get and display each record  while(SQLResult.next())  {    UId = SQLResult.getString("uid");    FName = SQLResult.getString("fname");    LName = SQLResult.getString("lname");     out.println("<tr><td>" + UId + "</td><td>" +  FName + "</td><td>" + LName + "</td></tr>");  } 

Кстати, ResultSetобъект также поставляется с удобным prev()методом, который позволяет отображать предыдущую запись.

Этот getString()метод используется для доступа к конкретным столбцам в записи, которая в данный момент проверяется; эти значения хранятся в виде строк в документе JSP. В дополнении к getString()методу, вы можете также использовать getInt(), getTimeStamp()и getBoolean()методы для получения значений столбцов в качестве типов переменных специфично.

8. Наконец, каждый набор результатов, возвращаемый после запроса, занимает некоторое количество памяти - и если ваша система, вероятно, испытывает большую нагрузку, рекомендуется использовать различные close()методы для освобождения памяти.

 // close connection  SQLResult.close();  SQLStatement.close();  Conn.close(); 

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

Как твое имя?

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

Мы будем использовать одну страницу для всей операции - переменная submit (вы помните эту технику, не так ли?) Используется для решения, отображать ли исходную форму или страницу результатов. Взглянем:

 <html>  <head>  <basefont face="Arial">  </head>   <body>  <center>  <%  // check submit state  String submit = request.getParameter("submit");   // form not yet submitted  // display initial page  if(submit == null)  {  %>   <form action="view.jsp" method="GET">  Enter your name:&nbsp;  <input type="text" name="name" size="10"> &nbsp; <input  type="submit" name="submit" value="Go"> </form>   <%  }  // form submitted, display result  else  {  %>   <%@ page language="java" import="java.sql.*" %>   <%  // get username  String uid = request.getParameter("name");   // define database parameters  String host="localhost";  String user="us867";  String pass="jsf84d";  String db="db876";  String conn;  %>   <h2><% out.println(uid); %>'s Little Black Book</h2>  <hr>   <table border=1 cellspacing=4 cellpadding=4>  <tr>  <td><b>First name</b></td>  <td><b>Last name</b></td>  <td><b>Tel</b></td>  <td><b>Fax</b></td>  <td><b>Email address</b></td>  </tr>   <%  Class.forName("org.gjt.mm.mysql.Driver");   // create connection string  conn = "jdbc:mysql://" + host + "/" + db + "?user=" + user  + "&password=" + pass;   // pass database parameters to JDBC driver  Connection Conn = DriverManager.getConnection(conn);   // query statement  Statement SQLStatement = Conn.createStatement();   // generate query  String Query = "SELECT * FROM abook WHERE uid = '" + uid + "'";   // get result  ResultSet SQLResult = SQLStatement.executeQuery(Query);   // display records  // if available  while(SQLResult.next())  {    String FName = SQLResult.getString("fname");    String LName = SQLResult.getString("lname");    String Tel = SQLResult.getString("tel");    String Fax = SQLResult.getString("fax");    String Email = SQLResult.getString("email");     out.println("<tr><td>" + FName + "</td><td>" +  LName + "</td><td>" + Tel + "</td><td>" + Fax + "</td><td>" +  Email + "</td></tr>");  }  // close connections  SQLResult.close();  SQLStatement.close();  Conn.close();   }  %>   </table>  </center>  </body>  </html> 

Как видите, проверяя значение submitпеременной " ", мы успешно объединили как начальную страницу, так и страницу результатов в один JSP-скрипт. Этот сценарий просто принимает имя пользователя, подключается к базе данных и отображает записи для этого пользователя (при условии, что они существуют). Войдите в систему как "bill", "joe" или "john", чтобы просмотреть записи, доступные для этого пользователя.

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

 <%  if (Fax.equals("null"))  {  Fax = "&nbsp;";  }  %> 
Copyright Melonfire , 2000. Все права защищены.

Новые друзья

До сих пор мы просто использовали SELECTзапросы для извлечения информации из базы данных. Но как насчет того, чтобы положить что-то в?

Любители SQL знают, что это происходит с помощью INSERTзапроса. Итак, следующий пункт повестки дня включает добавление новых записей в адресную книгу. Вот форма, которую мы будем использовать:

 <html>  <head>  <basefont face="Arial">  </head>   <body>  <center>  <h2>Add Address Book Entry</h2>   <table border=0 cellspacing=5 cellpadding=5>  <form action="add_res.jsp" method="POST">   <tr>  <td><b>Username</b></td>  <td>  <select name="uid">  <!-- generate list of available usernames from database -->  <%@ page language="java" import="java.sql.*" %>  <%   // database parameters  String host="localhost";  String user="us867";  String pass="jsf84d";  String db="db876";  String connString;   // load driver  Class.forName("org.gjt.mm.mysql.Driver");   // create connection string  connString = "jdbc:mysql://" + host + "/" + db + "?user="        + user + "&password=" +  pass;   // pass database parameters to JDBC driver  Connection Conn = DriverManager.getConnection(connString);   // query statement  Statement SQLStatement = Conn.createStatement();   // generate query  String Query = "SELECT DISTINCT uid FROM abook";   // get result  ResultSet SQLResult = SQLStatement.executeQuery(Query);   // get and display each record    while(SQLResult.next())    {      String UId = SQLResult.getString("uid");       out.println("<option>" + UId);    }   // close connections  SQLResult.close();  SQLStatement.close();  Conn.close();   %>   </select>  </td>  </tr>   <tr>  <td>First name</td>  <td><input type="Text" name="fname" size="15"></td>  </tr>   <tr>  <td>Last name</td>  <td><input type="Text" name="lname" size="15"></td>  </tr>   <tr>  <td>Address</td>  <td><textarea name="address"></textarea></td>  </tr>   <tr>  <td>Tel</td>  <td><input type="Text" name="tel" size="10"></td>  </tr>   <tr>  <td>Fax</td>  <td><input type="Text" name="fax" size="10"></td>  </tr>   <tr>  <td>Email address</td>  <td><input type="Text" name="email" size="10"></td>  </tr>   <tr>  <td>Company</td>  <td><input type="Text" name="company" size="25"></td>  </tr>   <tr>  <td>Comment</td>  <td><input type="Text" name="comment" size="25"></td>  </tr>   <tr>  <td colspan=2><input type="submit" name="submit"  value="Add"></td> </tr>   </form>  </table>   </center>  </body>  </html> 

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

Как только форма заполнена и отправлена, управление переходит к «add_res.jsp», который заботится о фактическом выполнении INSERTоперации. Взглянем.

 <html>  <head>  <basefont face="Arial">  </head>  <body>  <center>   <%@ page language="java" import="java.sql.*" %>   <%  // add_res.jsp   // form data  String uid = request.getParameter("uid");  String fname = request.getParameter("fname");  String lname = request.getParameter("lname");  String address = request.getParameter("address");  String tel = request.getParameter("tel");  String fax = request.getParameter("fax");  String email = request.getParameter("email");  String company = request.getParameter("company");  String comment = request.getParameter("comment");   // database parameters  String host="localhost";  String user="us867";  String pass="jsf84d";  String db="db876";  String conn;   Class.forName("org.gjt.mm.mysql.Driver");   // create connection string  conn = "jdbc:mysql://" + host + "/" + db + "?user=" + user          f  + "&password=" + pass;   // pass database parameters to JDBC driver  Connection Conn = DriverManager.getConnection(conn);   // query statement  Statement SQLStatement = Conn.createStatement();   // generate query  String Query = "INSERT INTO abook (id, uid, fname, lname,  tel, fax, email, addr, company, comment) VALUES (NULL, '" +  uid + "', '" + fname + "', '" + lname + "', '" + tel  + "', '" + fax + "', '" + email + "', '" + address + "',  '" + company + "', '" + comment + "')";   // get result code  int SQLStatus = SQLStatement.executeUpdate(Query);   if(SQLStatus != 0)  {  out.println("Entry succesfully added.");  }  else  {  out.println("Error! Please try again.");  }   // close connection  SQLStatement.close();  Conn.close();   %>   </center>  </body>  </html> 

Этот пример демонстрирует еще один метод Statementобъекта, executeUpdate()метод, используемый для INSERTили UPDATEопераций. Этот метод возвращает код результата, указывающий количество строк, затронутых операцией - в приведенном выше примере этот код результата должен быть равен 1. В случае, если это не ... у вас возникли проблемы!

В этот момент следует отметить, что если ваше INSERTутверждение содержит специальные символы, которые необходимо экранировать (скажем, запятые или одинарные кавычки), вам лучше использовать PreparedStatementкласс, который автоматически заботится о экранировании специальных символов и обеспечивает некоторую производительность. преимущества также. Обсуждение PreparedStatementкласса выходит за рамки этого учебного пособия, но есть много документации, если вам когда-нибудь понадобится.
Copyright Melonfire , 2000. Все права защищены.


Адрес пересылки отсутствует

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

 <html>  <head>  <basefont face="Arial">  </head>   <body>  <center>  <%  // check submit state  String submit = request.getParameter("submit");   // form not yet submitted  // display initial page  if(submit == null)  {  %>   <form action="view.jsp" method="GET">  Enter your name:&nbsp;<input type="text" name="name"  size="10"> &nbsp; <input type="submit" name="submit"  value="Go"> </form>   <%  }  // form submitted, display result  else  {  %>   <%@ page language="java" import="java.sql.*" %>   <%  // get username  String uid = request.getParameter("name");   // define database parameters  String host="localhost";  String user="us867";  String pass="jsf84d";  String db="db876";  String conn;  %>   <h2><% out.println(uid); %>'s Little Black Book</h2>  <hr>   <table border=1 cellspacing=4 cellpadding=4>  <tr>  <td><b>First name</b></td>  <td><b>Last name</b></td>  <td><b>Tel</b></td>  <td><b>Fax</b></td>  <td><b>Email address</b></td>  <td>&nbsp;</td>  </tr>   <%  Class.forName("org.gjt.mm.mysql.Driver");   // create connection string  conn = "jdbc:mysql://" + host + "/" + db + "?user="  + user + "&password=" + pass;   // pass database parameters to JDBC driver  Connection Conn = DriverManager.getConnection(conn);   // query statement  Statement SQLStatement = Conn.createStatement();   // generate query  String Query = "SELECT * FROM abook WHERE uid = '" + uid + "'";   // get result  ResultSet SQLResult = SQLStatement.executeQuery(Query);   // display records  // if available  while(SQLResult.next())  {    String FName = SQLResult.getString("fname");    String LName = SQLResult.getString("lname");    String Tel = SQLResult.getString("tel");    String Fax = SQLResult.getString("fax");    String Email = SQLResult.getString("email");     // get the record number HERE    String ID = SQLResult.getString("id");     // add an edit link to each record with the ID    out.println("<tr><td>" + FName + "</td><td>"  + LName + "</td><td>" + Tel + "</td><td>" + Fax + "</td><td>"  + Email + "</td><td><a + href=edit.jsp?id=" ID + ">edit this  entry</a></td></tr>");  }   // close connections  SQLResult.close();  SQLStatement.close();  Conn.close();   }  %>   </table>  </center>  </body>  </html> 

Нажав на эту ссылку, вы активируете скрипт «edit.jsp» и передадите ему номер записи через URL GETметод.

Давайте теперь посмотрим на "edit.jsp"

  <html>  <head>  <basefont face="Arial">  </head>   <body>  <center>  <h2>Update Address Book Entry</h2>   <%@ page language="java" import="java.sql.*" %>   <%  // form variables  String fid = request.getParameter("id");  int id = Integer.parseInt(fid);   String fname = "";  String lname = "";  String tel = "";  String fax = "";  String email = "";  String address = "";  String company = "";  String comment = "";   // database parameters  String host="localhost";  String user="us867";  String pass="jsf84d";  String db="db876";  String conn;   Class.forName("org.gjt.mm.mysql.Driver");   // create connection string  conn = "jdbc:mysql://" + host + "/" + db + "?user=" + user  + "&password=" + pass;   // pass database parameters to JDBC driver  Connection Conn = DriverManager.getConnection(conn);   // query statement  Statement SQLStatement = Conn.createStatement();   // generate query  String Query = "SELECT * FROM abook where id=" + id;   // get result  ResultSet SQLResult = SQLStatement.executeQuery(Query);   // get and display record  fname = SQLResult.getString("fname");  lname = SQLResult.getString("lname");  tel = SQLResult.getString("tel");  fax = SQLResult.getString("fax");  email = SQLResult.getString("email");  address = SQLResult.getString("addr");  company = SQLResult.getString("company");  comment = SQLResult.getString("comment");   // close connection  SQLResult.close();  SQLStatement.close();  Conn.close();  %>   <table border=0 cellspacing=5 cellpadding=5>  <form action="edit_res.jsp" method="POST">   <input type="hidden" name="id" value="<%= id %>">   <tr>  <td>First name</td>  <td><input type="Text" name="fname" size="15" value="<%=  fname %>"></td> </tr>   <tr>  <td>Last name</td>  <td><input type="Text" name="lname" size="15" value="<%=  lname %>"></td> </tr>   <tr>  <td>Address</td>  <td><textarea name="address"><%= address %></textarea></td> </tr>   <tr>  <td>Tel</td>  <td><input type="Text" name="tel" size="10" value="<%=  tel %>"></td> </tr>   <tr>  <td>Fax</td>  <td><input type="Text" name="fax" size="10" value="<%=  fax %>"></td> </tr>   <tr>  <td>Email address</td>  <td><input type="Text" name="email" size="10" value="<%=  email %>"></td> </tr>   <tr>  <td>Company</td>  <td><input type="Text" name="company" size="25" value="<%=  company %>"></td> </tr>   <tr>  <td>Comment</td>  <td><input type="Text" name="comment" size="25" value="<%=  comment %>"></td> </tr>   <tr>  <td colspan=2><input type="submit" name="submit"  value="Update"></td> </tr>   </form>  </table>   </center>  </body>  </html> 

Как вы можете видеть, как только «edit.jsp» получает номер записи, он подключается к базе данных, извлекает запись, а затем генерирует простую форму с уже заполненными значениями (обратите внимание на использование нами конструкции ярлыка <%= %>для отображения значений переменных ). Пользователь тогда может свободно изменять информацию, отображаемую в форме; После этого форма отправляется в «edit_res.jsp», который выполняет UPDATEоперацию.

 <html>  <head>  <basefont face="Arial">  </head>  <body>  <center>   <%@ page language="java" import="java.sql.*" %>   <%  // edit_res.jsp   // form data  String fid = request.getParameter("id");  int id = Integer.parseInt(fid);   String fname = request.getParameter("fname");  String lname = request.getParameter("lname");  String address = request.getParameter("address");  String tel = request.getParameter("tel");  String fax = request.getParameter("fax");  String email = request.getParameter("email");  String company = request.getParameter("company");  String comment = request.getParameter("comment");   // database parameters  String host="localhost";  String user="root";  String pass="";  String db="test";  String conn;   Class.forName("org.gjt.mm.mysql.Driver");   // create connection string  conn = "jdbc:mysql://" + host + "/" + db + "?user=" + user  + "&password=" + pass;   // pass database parameters to JDBC driver  Connection Conn = DriverManager.getConnection(conn);   // query statement  Statement SQLStatement = Conn.createStatement();   // generate query  String Query = "UPDATE abook SET fname='" + fname + "', lname='"  + lname + "', tel='" + tel + "', fax='" + fax + "', email='"  + email + "', addr='" + address + "', company='"  + company  + "', comment='"  + comment + "' WHERE id=" + id;   // get result code  int SQLStatus = SQLStatement.executeUpdate(Query);   if(SQLStatus != 0)  {  out.println("Entry successfully updated.");  }  else  {  out.println("Error! Please try again.");  }   // close connection  SQLStatement.close();  Conn.close();   %>   </center>  </body>  </html> 

Конечно, мы могли бы объединить все приведенные выше сценарии в один документ JSP - но мы оставим это упражнение вам на данный момент.
Copyright Melonfire , 2000. Все права защищены.


Убираться

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

Во-первых, необходимо изменить начальную страницу списка, чтобы включить ссылку для удаления определенной записи - это похоже на способ добавления ссылки «изменить эту запись». Предполагая, что об этом позаботятся, следует вызвать скрипт «delete.jsp» с номером удаляемой записи. Итак, так же, как у вас есть ссылка

 "<a href=edit.jsp?id=" + ID + ">edit this entry</a>" 
теперь у вас будет дополнительная ссылка
 "<a href=delete.jsp?id=" + ID + ">delete this entry</a>" 

Давайте посмотрим на "delete.jsp".

 <html>  <head>  <basefont face="Arial">  </head>  <body>  <center>   <%@ page language="java" import="java.sql.*" %>   <%  // delete.jsp   // form data  String fid = request.getParameter("id");  int id = Integer.parseInt(fid);   // database parameters  String host="localhost";  String user="us867";  String pass="jsf84d";  String db="db876";  String conn;   Class.forName("org.gjt.mm.mysql.Driver");   // create connection string  conn = "jdbc:mysql://" + host + "/" + db + "?user=" + user  + "&password=" + pass;   // pass database parameters to JDBC driver  Connection Conn = DriverManager.getConnection(conn);   // query statement  Statement SQLStatement = Conn.createStatement();   // generate query  String Query = "DELETE FROM abook WHERE id=" + id;   // get result code  int SQLStatus = SQLStatement.executeUpdate(Query);   if(SQLStatus != 0)  {  out.println("Entry successfully deleted.");  }  else  {  out.println("Error! Please try again.");  }   // close connection  SQLStatement.close();  Conn.close();   %>   </center>  </body>  </html> 

И это все, что у нас есть в этом выпуске The JSP Files. В следующий раз мы рассмотрим возможности управления сеансами HTTP, доступные в JSP, поэтому обязательно вернитесь к этому!

Примечание. Все примеры в этой статье были протестированы на Linux / i586 с Tomcat 3.2 и JServ 1.1. Примеры являются только иллюстративными и не предназначены для производственной среды. YMMV!
Copyright Melonfire , 2000. Все права защищены.


Файлы JSP - Часть 6: Благодать

Идеальное состояние

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

На этой неделе в «Файлах JSP» мы рассмотрим еще одну очень интересную тему - проблему поддержания «состояния» на веб-сайте. Мы рассмотрим два распространенных решения этой проблемы - файлы cookie и сеансы на основе сервера - и на простых примерах продемонстрируем доступные конструкции JSP, которые помогут вам идентифицировать и отслеживать запросы клиентов на вашем веб-сайте.

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

Потрачено впустую, чувак!

Это одна из тех вещей, которые гики говорят друг другу, когда хотят произвести впечатление на молодых женщин, находящихся на слуху: «HTTP - это протокол без состояния, а Интернет - среда разработки без состояния». Говоря простым языком, все это означает, что протокол передачи гипертекста, являющийся основой Интернета, не может сохранить память идентификатора каждого клиента, который подключается к веб-сайту, и поэтому обрабатывает каждый запрос веб-страницы. как уникальная и независимая связь, не имеющая никакого отношения к предшествующим ей связям - очень похожая на поведение некоторых сегодняшних более предприимчивых подростков, которые напиваются каждую ночь, просыпаются на следующее утро без памяти о том, что произошло и выходить вечером снова, чтобы повторить то же самое ...

Теперь, пока вы бесцельно перемещаетесь с одного сайта на другой, это работает без проблем. Но что, если вы решили купить несколько дисков с CDNow.com? В «среде без состояния» было бы очень трудно отслеживать все элементы, которые вы включили в шорт-лист для покупки, так как HTTP-протокол без состояния не позволяет отслеживать выбранные элементы.

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

Почему они называются «куки»? Агентство по связям с общественностью, очевидно, спало за рулем.

Несколько Основных Правил

Поскольку файлы cookie используются для записи информации о ваших действиях на определенном сайте, они могут быть прочитаны только тем сайтом, который их создал. Например, Yahoo и Deja.com сохраняют ваше имя пользователя в файле cookie на вашем жестком диске и используют эту информацию для автоматического заполнения форм для входа при следующем посещении их веб-сайтов. Это все равно что пойти в шикарный ресторан, и мэтр назвал бы тебя по имени (что-то, чего не случалось с нами в последнее время!)

Прежде чем приступить к изучению технологии cookie-файлов, приведем несколько основных правил:

  1. Один домен не может устанавливать более двадцати файлов cookie. Размер одного файла cookie не может превышать 4 КБ. Максимальное количество файлов cookie, которое можно установить, составляет 300.
  2. Наиболее распространенный способ передачи файла cookie клиенту - через HTTP-заголовок «Set-Cookie».
  3. Печенье обычно имеет пять типов атрибутов.

    Первая из них - это NAME=VALUEпара, используемая для хранения такой информации, как имя пользователя, адрес электронной почты или номер кредитной карты. NAMEЯвляется строка , используемая для идентификации куки, в то время как VALUEесть данные , которые будут храниться в куки. Например,

     clarkkent=superman 

    EXPIRESАтрибут определяет дату , на которую куки автоматически удаляются из системы. Дата должна быть в формате «день недели, дд-мон-гг, чч: мм: сс GMT». Например,

     expires="Sun, 31-Dec-2030 17:51:06 GMT" 

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

    PATHАтрибут используется для установки каталог верхнего уровня на веб - сервере , с которого можно получить доступ печенье. В большинстве случаев это установлено

     path=/ 

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

    DOMAINАтрибут используется для указания домена , который куки связан с, а SECUREатрибут указывает , что куки должны быть установлены только если существует безопасный протокол между браузером и сервером.

  4. Из всех пяти атрибутов первый является единственным, который не является обязательным.

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

Copyright Melonfire , 2000. Все права защищены.


Учимся писать ...

Теперь существует бесчисленное множество способов создания и чтения файлов cookie в браузере клиента - вы можете использовать Javascript, вы можете использовать PHP, вы можете использовать любой из замечательных языков программирования. Однако наша проблема здесь связана с JSP - поэтому давайте рассмотрим пример, который демонстрирует, как читать и записывать куки.

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

 <%  // counter.jsp   // declare some variables  Cookie cookieCounter = null;   // the cookie you want  String cookieName = "counter";  int cookieFound = 0;   // a few more useful variables  String tempString;  int count=0;   // get an array of all cookies available on client  Cookie[] cookies = request.getCookies();   // iterate through array looking for your cookie  for(int i=0; i<cookies.length; i++)  {    cookieCounter = cookies[i];    if (cookieName.equals(cookieCounter.getName()))  {  cookieFound = 1;    break;  }   }   // if found  if(cookieFound == 1)  {   // get the counter value as string  tempString = cookieCounter.getValue();   // convert it to a number  count = Integer.parseInt(tempString);   // increment it           &nbspf;  count++;   // back to a string  tempString = Integer.toString(count);   // store it in the cookie for future use  cookieCounter.setValue(tempString);   // set some other attributes  cookieCounter.setMaxAge(300);  cookieCounter.setPath("/");   // send cookie to client  response.addCookie(cookieCounter);  }  // if not found  else  {  // create a new cookie with counter 0  Cookie alpha = null;  alpha = new Cookie("counter", "0");  alpha.setMaxAge(300);  alpha.setPath("/");  response.addCookie(alpha);  }  %>   <html>  <head>  <basefont face="Arial">  </head>   <body>   <%  // display appropriate message  if (count > 0)  {  out.println("You have visited this page " + count + "  time(s)! Don't you have anything else to do, you bum?! ");  } else { out.println("Welcome, stranger!"); }  %>   </body>  </html> 

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

Первое, что вам нужно знать, это как создать cookie на клиенте - это выполняется с помощью следующего кода:

 <%  Cookie alpha = null;  alpha = new Cookie("counter", "0");  alpha.setMaxAge(300);  alpha.setPath("/");  response.addCookie(alpha);  %> 

The first two lines create a new instance of a Cookie object - " alpha ". The cookie variable " counter " is then initialized and set to the string " 0 ". Next, the setMaxAge() and setPath() methods of the Cookie object are used to set the expiry date (in seconds) and the cookie's availability, respectively. Finally, a call to the Response object's addCookie() method takes care of actually transmitting the cookie to the client.

As already mentioned, the only attribute which is not optional is the NAME=VALUE pair. If you'd like your cookie to remain available even after the user closes the browser, you should explicitly set an expiry date; if not, the cookie will be destroyed once the browser is closed.

The Cookie object also comes with a couple of other interesting methods.

  • setValue(someString) - sets the value of the cookie to someString
  • getValue() - returns the current value of the cookie
  • setPath(someURL) - sets the PATH attribute of a cookie to someURL
  • getPath() - returns the current value of the PATH attribute
  • setMaxAge(someSeconds) - sets the EXPIRES attribute of the cookie, in seconds
  • getMaxAge() - returns the current value of the EXPIRES attribute
  • setDomain(someURL) - sets the DOMAIN attribute of the cookie
  • getDomain() - returns the current value of the DOMAIN attribute
  • setSecure(flag) - sets the SECURE attribute of the cookie as either true or false
  • getSecure() - returns the current value of the SECURE attribute

Note that you can only save string values in a cookie with setValue() - which entails a lot of string-to-number-to-string conversions if you actually want to store a number (as in this example).

Copyright Melonfire , 2000. Все права защищены.

...And Read

So that takes care of writing a cookie - but how about reading it? Вот код

 <%  // declare some variables  Cookie cookieCounter = null;   // the cookie you want  String cookieName = "counter";  int cookieFound = 0;   // a few more useful variables  String tempString;  int count=0;   // get an array of all cookies available on client  Cookie[] cookies = request.getCookies();   // iterate through array looking for your cookie  for(int i=0; i<cookies.length; i++)  {    cookieCounter = cookies[i];    if (cookieName.equals(cookieCounter.getName()))  {  cookieFound = 1;    break;  }   }  %> 

Before you can read the cookie, you need to find it on the client's hard drive. Since JSP does not currently allow you to directly locate and identify the cookie by name, you need to iterate through all available cookies until you find the one you're looking for. In the example above, the " for " loop does just that; if and when it finds the cookie, it sets the " cookieFound " variable to 1 and breaks out of the loop.

At this point, the cookie is stored in the Cookie object " cookieCounter ". You can then use the getValue() object method to get the current value of the cookie variable, and use it in your script.

  <%  // if found  if(cookieFound == 1)  {   // get the counter value as string  tempString = cookieCounter.getValue();   // convert it to a number  count = Integer.parseInt(tempString);   // increment it  count++;   // back to a string  tempString = Integer.toString(count);   // store it in the cookie for future use  cookieCounter.setValue(tempString);   // set some other attributes  cookieCounter.setMaxAge(300);  cookieCounter.setPath("/");   // send cookie to client  response.addCookie(cookieCounter);  }  %> 
What's In A Name?

Once you've understood these two fundamental techniques, the rest of the code should be simple to decipher. If a cookie is found, the counter variable is incremented, and the setValue() method is used to write a new value to the cookie; this counter variable is then displayed on the page. If a cookie is not found, it implies that this is the user's first visit to the page (or a visit made after a previous cookie has expired); a new cookie is set and an appropriate message displayed.

Again, since this example deals with numbers rather than strings, innumerable contortions are required to convert the string value in the cookie to a number, increment it, and then convert it back to a string for storage in the cookie.

Here's another example, this one a simple form. Enter your name and submit the form - a cookie will be created containing the name you entered. When you next visit the page, your name will be automatically filled in for you.

 <%  // form.jsp   // declare some variables  Cookie thisCookie = null;   // the cookie you want  String cookieName = "username";  int cookieFound = 0;  String username = "";   // get an array of all cookies available on client  Cookie[] cookies = request.getCookies();   // iterate through array looking for your cookie  for(int i=0; i<cookies.length; i++)  {    thisCookie = cookies[i];    if (cookieName.equals(thisCookie.getName()))  {  cookieFound = 1;    break;  }   }   // if found  if(cookieFound == 1)  {  // get the counter value  username = thisCookie.getValue();  }  %>    <html>  <head>  <basefont face="Arial">  </head>   <body>   <form action="login.jsp" method="post">  <table>   <tr>  <td>Your name</td>  <td><input type=text name=username value="<%=  username %>">&nbsp;<input type="Submit" value="Click  me"></td> </tr>    </table>  </form>   </body>  </html> 

This is the initial login form, "form.jsp" - as you can see, it checks for the presence of a cookie, and uses it to fill in the account username if available.

When the form is submitted, "login.jsp" is called to process the data entered into the form; it will also set cookie attributes appropriately.

 <%  // login.jsp   // get values from form  String username = request.getParameter("username");   // create a new cookie to store the username  Cookie alpha = null;  alpha = new Cookie("username", username);  alpha.setMaxAge(300);  alpha.setPath("/");   // send it to client  response.addCookie(alpha);  %>   <html>  <head>  <basefont face="Arial">  </head>   <body>   Get lost, <b><%= username %></b>!   </body>  </html> 

Просто, да?

Copyright Melonfire , 2000. Все права защищены.

Plan B

The cookie-based approach is quite common; many Web sites use it, because it is flexible, simple, and independent of the server-side language (once the cookie has been saved to the client's hard drive, you can read it using JavaScript, or PHP, or JSP, or ...) The only problem: it is dependent on the cookie being accepted by the client.

And so, another common approach is the use of a "session" to store specific bits of information when a client visits a Web site; this session data is preserved for the duration of the visit, and is usually destroyed on its conclusion. A session can thus be considered a basket of information which contains a host of variable-value pairs; these variable-value pairs exist for the duration of the visit, and can be accessed at any point during it. This approach provides an elegant solution to the "stateless" nature of the protocol, and is used on many of today's largest sites to track and maintain information for personal and commercial transactions.

Every session created is associated with a unique identification string, or "session ID"; this string is sent to the client, while a temporary entry with the same unique identification number is created on the server, either in a flat file or in a database. It now becomes possible to register any number of "session variables" - these are ordinary variables, which can be used to store textual or numeric information, and can be read from, or written to, throughout the session.

The session ID is transmitted to the client either via a cookie, or via the URL GET method. The client, in turn, must reference each request with this session ID, so that the server knows which session each client is associated with and uses the appropriate session variables for each client. In case the client doesn't support cookies and the URL method is rejected or not used, session management capabilities and session variables will not be available to the client, and every request will be treated as though it were coming for the first time.

Sessions are typically left active for as long as the user's browser is open, or for a pre-defined period. Once the user's browser is closed, or the specified time period is exceeded, the session and all variables within it are automatically destroyed.

Session Dissection

Creating a JSP session is much simpler than writing a cookie. To demonstrate this, here's the session equivalent of the cookie-based counter you saw a few pages back.

 <html>  <head>  </head>   <body>   <%  // get the value of the session variable  Integer visits = (Integer)session.getValue("counter");   // if null  if (visits == null)  {  // set it to 0 and print a welcome message  visits = new Integer(0);  session.putValue("counter", visits);  out.println("Welcome, stranger!");  }  else  {  // else increment and write the new value  visits = new Integer(visits.intValue() + 1); session.putValue  ("counter", visits); out.println("You have visited this  page " + visits + " time(s)! Don't you have anything  else to do, you bum?! "); }  %>   </body>  </html> 

There isn't much you have to do to create a session - simply use the
putValue() method of the Session object to create one or more session variable, and JSP will automatically create a session and register the variables. You can then use the getValue() method to retrieve the values of the session variables automatically.

An important point to be noted here is that it is necessary to typecast the session variable while using getValue() - in the example above, we've specifically stated the type of the variable in parentheses before assigning it to a regular JSP variable. Since JSP allows you to bind objects to the session, you can bind an Integer object and thereby bypass some of the string-to-number conversion routines in the equvalent cookie example.

With this information in mind, the example above becomes much simpler to read. An "if" statement is used to take care of the two possible
alternatives: a first-time visitor (no prior session) or a returning visitor (pre-existing session). Depending on whether or not the "counter" variable exists, appropriate action is taken.

The Session object also comes with a bunch of other interesting methods - here are some of them:

  • getId() - returns a string containing the unique session ID
  • setMaxInactiveInterval(someSeconds) - keeps the session active for someSeconds duration after the last client request
  • invalidate() - destroy the session
  • getAttribute() and setAttribute() - try these if getValue() and putValue() don't work
  • getCreationTime() - returns the time at which this session was created, in seconds, as an offset from midnight January 1 1970

Copyright Melonfire , 2000. Все права защищены.

Access Denied

Here's another simple example which demonstrates some of the methods above, and also illustrates how JSP sessions can be used to protect Web pages with sensitive information.

This example presents a form ("start.html") asking for your name, and takes you to a new page ("login.jsp") once you submit the form. "login.jsp" creates a session to store the name you entered, and offers a link to "rootshell.jsp", which is the sensitive file to be protected.

So long as the session is active, any attempt to access the page "rootshell.jsp" will succeed. On the flip side, if a session is not active, any attempt to access "rootshell.jsp" by bypassing the initial form will fail, and the user will be redirected to "start.html".

This is a relatively primitive example, but serves to demonstrate one of the more common uses of session variables.

Все перенаправление в этом примере выполняется с помощью Responseобъекта (вы помните это, не так ли?)

 <html>  <head>  <basefont face="Arial">  </head>   <body>  <!-- start.html -->  <form action="login.jsp" method="post">  <table>   <tr>  <td>Your name</td>  <td><input type=text name=username>&nbsp;<input  type="Submit" value="Click me"></td> </tr>    </table>  </form>   </body>  </html> 

После того, как форма отправлена, «login.jsp» вступает во владение.

 <html>  <head>  <basefont face="Arial"  </head>   <body>  <%   // get the form variable  String username = request.getParameter("username");   // create a session  session.putValue("username", username);   // set a timeout period  session.setMaxInactiveInterval(300);   // display a link to the protected file  out.println("Thank you for using this service.");  out.println("Click <a href=rootshell.jsp>here</a> for  root access"); %>   </body>  </html> 

А вот и сверхсекретная страница.

 <html>  <head>  <basefont face="Arial">  </head>   <body>  <%  // rootshell.jsp   // get the username from the session  String username = (String)session.getValue("username");   // if null, security breach!  if (username == null)  {  response.setHeader("Location", "start.html");  }  else  {  // display the protected page  %>   Welcome to your root shell, <b><%= username %></b>!  <p>  Your session ID is <% out.println( session.getId() ); %>  <p>  This session will expire in <% out.println(  session.getMaxInactiveInterval() ); %> seconds.   <%  }  %>   </body>  </html> 

Чтобы проверить это, сначала войдите в систему и найдите свой путь к «rootshell.jsp» - у вас не должно возникнуть проблем с доступом к нему. Затем закройте браузер, запустите его снова и попробуйте перейти к «rootshell.jsp», не проходя процесс входа в систему; Вы должны быть автоматически перенаправлены на страницу входа.

И это все. Теперь у вас должно быть достаточно четкое представление о том, как JSP пытается решить проблему «протокола без сохранения состояния», вместе с некоторым пониманием того, как создавать и использовать как файлы cookie на стороне клиента, так и сеансы на стороне сервера. Иди потренируйся!

Примечание. Все примеры в этой статье были протестированы на Linux / i586 с Tomcat 3.2 и JServ 1.1. Примеры являются только иллюстративными и не предназначены для производственной среды. YMMV!
Copyright Melonfire , 2000. Все права защищены.

Файлы JSP - Часть 7: Ошибки, Бины и Банки

Сгорая

Ни один программист, независимо от того, насколько он хорош, все время пишет код без ошибок. Итак, большинство языков программирования имеют встроенные возможности для выявления ошибок и принятия корректирующих мер. Это действие может быть таким простым, как отображение сообщения об ошибке, или таким же сложным, как нагревание внутренних частей вашего компьютера, пока они не загорятся (просто шучу!)

На следующих нескольких страницах мы рассмотрим некоторые методы управления ошибками, доступные в JSP, а также продемонстрируем некоторые из директив JSP, используемых для интеграции автономных JavaBean-компонентов в ваши JSP-скрипты.

Bugathon

Во-первых, быстрый урок семантики. Существует важное различие между «ошибками» и «исключениями».

«Ошибки» JSP обычно невозможно отследить, поскольку они обычно связаны с проблемами, не зависящими от разработчика приложения - такими, как нехватка памяти на сервере, отсутствующие файлы или поврежденная файловая система.

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

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

Исключительно умный

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

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

  2. Создайте соответствующую «страницу ошибки», необязательно используя объект Exception, чтобы получить более подробную информацию об исключении.

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

 <%  int a = 19;  int b = 0;  int c = a/b;  %> 

Вот вывод:

 Error: 500  Internal Servlet Error:  javax.servlet.ServletException: / by zero  at org.apache.jasper.runtime.PageContextImpl.handlePage  Exception(PageContextImp  l.java:459)  at _0002fb_0002ejspb_jsp_2._jspService  (_0002fb_0002ejspb_jsp_2.java:72)  at org.apache.jasper.runtime.HttpJsp  Base.service(HttpJspBase.java:119)  at javax.servlet.http.HttpServlet.  service(HttpServlet.java:853)  at org.apache.jasper.servlet.JspServlet  $JspServletWrapper.service(JspServlet.ja  va:177)  at org.apache.jasper.servlet.JspServlet.  serviceJspFile(JspServlet.java:318)  at org.apache.jasper.servlet.JspServlet.  service(JspServlet.java, Compiled  Code)  at javax.servlet.http.HttpServlet.  service(HttpServlet.java:853)  at org.apache.tomcat.core.ServletWrapper.  doService(ServletWrapper.java:404)  at org.apache.tomcat.core.Handler.service  (Handler.java:286)  at org.apache.tomcat.core.ServletWrapper.  service(ServletWrapper.java:372)  at org.apache.tomcat.core.ContextManager.  internalService(ContextManager.java:79  7)  at org.apache.tomcat.core.ContextManager.  service(ContextManager.java:743)  at org.apache.tomcat.service.connector.  Ajp12ConnectionHandler.processConnection  (Ajp12ConnectionHandler.java:166)  at org.apache.tomcat.service.TcpWorkerThread.  runIt(PoolTcpEndpoint.java,  Compiled Code)  at org.apache.tomcat.util.ThreadPool$Control  Runnable.run(ThreadPool.java,  Compiled Code)  at java.lang.Thread.run(Thread.java, Compiled Code)  Root cause:  java.lang.ArithmeticException: / by zero  at _0002fb_0002ejspb_jsp_2._jspService  (_0002fb_0002ejspb_jsp_2.java:62)  at org.apache.jasper.runtime.HttpJspBase.  service(HttpJspBase.java:119)  at javax.servlet.http.HttpServlet.service  (HttpServlet.java:853)  at org.apache.jasper.servlet.JspServlet$Jsp  ServletWrapper.service(JspServlet.ja  va:177)  at org.apache.jasper.servlet.JspServlet.  serviceJspFile(JspServlet.java:318)  at org.apache.jasper.servlet.JspServlet.  service(JspServlet.java, Compiled  Code)  at javax.servlet.http.HttpServlet.service  (HttpServlet.java:853)  at org.apache.tomcat.core.ServletWrapper.  doService(ServletWrapper.java:404)  at org.apache.tomcat.core.Handler.service  (Handler.java:286)                             &nbsfp;  at org.apache.tomcat.core.ServletWrapper.  service(ServletWrapper.java:372)  at org.apache.tomcat.core.ContextManager.  internalService(ContextManager.java:79  7)  at org.apache.tomcat.core.ContextManager.  service(ContextManager.java:743)  at org.apache.tomcat.service.connector.  Ajp12ConnectionHandler.processConnection  (Ajp12ConnectionHandler.java:166)  at org.apache.tomcat.service.TcpWorkerThread.  runIt(PoolTcpEndpoint.java,  Compiled Code)  at org.apache.tomcat.util.ThreadPool$Control  Runnable.run(ThreadPool.java,  Compiled Code)  at java.lang.Thread.run(Thread.java, Compiled Code) 

Уродливый, а?

Чтобы обработать это исключение в JSP, чтобы пользователю никогда не приходилось видеть что-то ужасное, вам нужно просто добавить

 <%@ page errorPage="error.jsp" %> 

к сценарию, чтобы он выглядел так:

 <%@ page errorPage="error.jsp" %>  <%  int a = 19;  int b = 0;  int c = a/b;  %> 

Исключение, выданное сценарием, теперь будет перехвачено JSP и автоматически направлено в «error.jsp». Давайте посмотрим на это дальше.
Copyright Melonfire , 2000. Все права защищены.

Плохие новости

Подпрограмма обработки исключений error.jsp может быть настолько простой или сложной, насколько вы захотите. Если вы хотите что-то дружелюбное и простое для понимания, вы можете использовать следующее:

 <html>  <head>  <basefont face="Arial">  </head>   <body bgcolor="white">  <h2>Oops!</h2>  Something bad just happened.  Click here to go back to the main page. </body>   </html> 

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

Приведенный выше скрипт просто уведомляет пользователя о том, что произошла ошибка; в нем ничего не говорится о типе ошибки или причинах ее возникновения. Если вы также хотите отобразить это, вам нужно использовать встроенный объект Exception для получения информации об исключении. В следующем примере используется модифицированный файл «error.jsp», чтобы проиллюстрировать это:

 <%@ page isErrorPage="true" %>  <html>  <head>  <basefont face="Arial">  </head>   <body bgcolor="white">  <h2>Oops!</h2>  Something bad just happened:  <br>  <b><i><%= exception.getMessage() %></i></b>   </body>  </html> 

И на этот раз вывод будет немного более полезным.

 Oops!  Something bad just happened:  / by zero 

Обратите особое внимание на первую строку сценария; директива

 <%@ page isErrorPage="true" %> 

сообщает JSP, что это страница с ошибкой, и инициализирует экземпляр объекта Exception для использования.

Объект Exception поставляется с несколькими полезными методами -
exception.getMessage()метод используется для получения описания ошибки, а exception.printStackTrace()метод используется для печати информации об отладке.

Вы бросаете (), я поймаю

Также возможно использовать конструкцию Java throw, чтобы искусственно вызвать исключение в вашем скрипте JSP. Это удобно, например, при проверке данных поля формы - если введенные значения не в ожидаемом формате, вы можете вызвать исключение (с информативным сообщением об ошибке) и перенаправить пользователя на страницу ошибки.

Вот пример того, как это можно использовать. Это простая форма, которая просит вас ввести номер

 <html>  <head>  <basefont face="Arial">  </head>   <body>   <form action="number.jsp">  Enter a number between 1 and 3  <input type=text name=number size=1> </form>   </body>  </html> 

и это серверный JSP-скрипт, который проверяет его на наличие ошибок и выдает исключение, если определенные условия не выполняются.

 <html>  <head>  <basefont face="Arial">  </head>   <body>  <%@ page errorPage="error.jsp" %>  <%  String temp = request.getParameter("number");   int number = Integer.parseInt(temp);   if (number != 2)  {  throw new Exception ("How dumb can you get?!") ;  }  else  {  out.println("Hmmm...maybe you're not as dumb as you look!");  }  %>   </body>  </html> 

Далее кратко рассмотрим JavaBeans и как они интегрируются в среду JSP.
Copyright Melonfire , 2000. Все права защищены.

Мешок фасоли

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

Мы не будем вдаваться в подробности создания JavaBean здесь - есть бесчисленные учебники по этой теме, в том числе хороший от Sun Microsystems . Вместо этого мы просто кратко коснемся конструкций JSP, которые позволят вам импортировать Bean-компонент в ваш JSP-скрипт, установить свойства Bean и получить доступ к методам Bean.

JavaBeans вводятся в сценарий JSP с помощью <jsp:useBean>действия, которое создает экземпляр Bean-компонента и определяет область его действий.

Следующий фрагмент кода создает экземпляр Bean-компонента «iceCream», идентифицирует его с помощью уникального идентификатора «vanilla» и определяет его область действия, ограниченную «страницей».

 <jsp:useBean id="vanilla" scope="page" class="iceCream">  </jsp:useBean> 

scopeАтрибут " " выше определяет степень влияния Бина. Например, « scope=page» означает, что экземпляр будет оставаться активным для текущей страницы, а « scope=session» означает, что экземпляр будет оставаться доступным на протяжении всего сеанса.

Принимая это в банк

Тесно связан с <jsp:useBean>is <jsp:setProperty>, обычно используется для установки свойств Бина; эти свойства могут быть установлены явно или на основе параметров, доступных в объекте Request (вы помните это, не так ли?)

В следующем фрагменте кода используется <jsp:setProperty>действие, чтобы присвоить значение «7683» свойству Bean « accountBalance». Обратите внимание, что <jsp:setProperty>действие ссылается на экземпляр ранее определенного Бина с именем «account»

 <jsp:useBean id="account" scope="page" class="Bank">  <jsp:setProperty name="account" property="accountBalance"  value="7683" /> </jsp:useBean> 

Если вы хотите установить свойства экземпляра на основе данных в объекте Request - скажем, значения формы - вы можете использовать

 <jsp:setProperty name="account" property="*" /> 

и JSP будет автоматически перебирать объект запроса, сопоставлять имена параметров с доступными свойствами Bean и назначать значения соответствующим образом.

Поднимая жару

Чтобы проиллюстрировать, как это работает, мы написали простой Бин, который принимает значения температуры и преобразует их между шкалами Цельсия и Фаренгейта. /#l#http://www.webmasterbase.com/examples/jspfiles/tempera.zip/#lt#/ Вот так ./#el#/

И вот страница, которая использует это:

 <html>  <head>  <basefont face="Arial">  </head>  <body>  <!-- initialize the Bean, set some defaults -->   <jsp:useBean id="c" scope="page" class="Temperature">  <jsp:setProperty name="c" property="celsius" value="10" />  </jsp:useBean>   <%  // get the current temperature  out.println("Temperature in Celsius is " + c.getCelsius() + "<p>");   // turn up the heat  c.setCelsius(36.8);   // get the current temperature  out.println("Temperature in Celsius is now " + c.getCelsius() + "<p>");   // convert the temperature to Fahrenheit  out.println(c.getCelsius() + " Celsius is " +  c.convertCelsiusToFahrenheit(c.getCelsius()) + " Fahrenheit<p>");   // ...and back again  out.println(c.getFahrenheit() + " Fahrenheit is " +  c.convertFahrenheitToCelsius(c.getFahrenheit()) + " Celsius<p>"); %>   </body>  </html> 

И вот вывод:

 Temperature in Celsius is 10.0  Temperature in Celsius is now 36.8  36.8 Celsius is 98.24 Fahrenheit  98.24 Fahrenheit is 36.8 Celsius 

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

Примечание. Все примеры в этой статье были протестированы на Linux / i586 с Tomcat 3.2 и JServ 1.1. Примеры являются только иллюстративными и не предназначены для производственной среды. YMMV!
Copyright Melonfire , 2000. Все права защищены.

Файлы JSP - Часть 8. Метки и мешки

Начало конца

За последние несколько недель мы провели вас по путеводителям по тонкостям JSP, начав с основ, таких как условные операторы и циклы, и быстро перейдя к более сложным вещам, таким как обработка форм, управление сеансами и обработка ошибок.

Но все хорошие вещи должны прийти к концу - и поэтому в этом последнем выпуске The JSP Files мы кратко коснемся нескольких других аспектов этого мощного серверного языка сценариев.

Играющий тег

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

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

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

Библиотеки тегов постепенно завоевывают популярность, и многие разработчики JSP выпускают пользовательские библиотеки тегов бесплатно в Интернете. Эти библиотеки обычно предназначены для конкретных задач - подключения к базе данных, манипуляции со строками и т. Д. - и предоставляют разработчикам JSP богатую возможность для разработки собственных проектов. В конце концов, зачем тратить время на написание кода Java для отправки сообщений электронной почты, когда вы можете найти многофункциональную, должным образом протестированную и бесплатную библиотеку тегов, которая делает то же самое в Интернете?

Смотреть внутрь

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

Затем вам нужен «дескриптор библиотеки тегов», файл XML, обычно идентифицируемый с расширением .TLD. Этот TLD содержит информацию о различных аспектах библиотеки тегов: имя тега и связанный с ним класс Java, краткое описание функциональных возможностей, а также необязательные атрибуты и содержимое тела.

Оба этих компонента обычно упакованы в файл JAR для удобства распространения.

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

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

После того, как вы загрузили копию библиотеки, вам нужно сообщить об этом Tomcat, прежде чем вы сможете начать ее использовать. Первым шагом здесь является определение контекста, в котором вы планируете использовать библиотеку - для целей этого примера мы предположим, что контекст - «/ test /». Затем скопируйте файл TLD из дистрибутива в каталог контекста «web-inf /», а основной файл JAR в каталог контекста «web-inf / lib /».

Последний шаг здесь - открыть файл «web.xml», который находится в каталоге «web-inf /», и изменить его так, чтобы он отражал новую библиотеку тегов - это достигается с помощью <taglib>директивы.

 <taglib> <taglib-uri>http://jakarta.apache.org/taglibs/  datetime-1.0</taglib-uri>  <taglib-location>/WEB-INF/datetime.tld</taglib-location>  </taglib> 

Этот элемент указывает местоположение библиотеки тегов, а также уникальный URI, используемый для ссылки на него.
Copyright Melonfire , 2000. Все права защищены.

Встреча Попай

На этом этапе вы можете начать использовать новую библиотеку тегов на своих страницах JSP. Сначала объявите это с помощью taglibдирективы " " - эта директива должна появляться перед любыми пользовательскими тегами на странице.

 <%@ taglib uri="http://jakarta.apache.org/taglibs/datetime-1.0"  prefix="popeye" %> 

URI является уникальным идентификатором для библиотеки тегов и должен соответствовать URI, указанному в «web.xml», в то время как префикс появляется при каждом вызове пользовательского тега и используется для различения тегов из разных библиотек на одной странице. ,

Как только библиотека была объявлена, вы можете начать использовать пользовательские теги в ваших JSP-скриптах. Рассмотрим следующий пример, в котором используется пользовательский тег из библиотеки DATETIME для вычисления количества секунд, прошедших с 1 января 1970 года.

 <html>  <head>  </head>  <body>   <%@ taglib uri="http://jakarta.apache.org/taglibs/datetime-1.0"  prefix="popeye" %>   The number of milliseconds since January 1, 1970 is <popeye:  currenttime/>   </body>  </html> 

И вывод:

 The number of milliseconds since January 1, 1970 is 987165837280 

Что делать, если вы просто хотите текущую дату и время? Комбинируя <currenttime>тег с <format>тегом, библиотека DATETIME делает это проще простого!

 <html>  <head>  </head>  <body>   <%@ taglib uri="http://jakarta.apache.org/taglibs/datetime-1.0"  prefix="popeye" %>   The current date and time is  <popeye:format pattern="hh:mm EEE MMMM dd yyyy"> <popeye:  currenttime/> </popeye:format>   </body>  </html> 

Если вам интересно, EEE и MMM, которые вы видите, имеют коды форматирования, используемые для определения формата, в котором должны быть напечатаны дата и время. Вот вывод:

 The current date and time is  06:22 Fri April 13 2001 

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

Как насчет создания списка дней или месяцев? Библиотека DATETIME получил вы покрыты его <weekdays>и <months>теги ...

 <html>  <head>  </head>  <body>   <%@ taglib uri="http://jakarta.apache.org/taglibs/datetime-1.0"  prefix="popeye" %>   <form>  Select a day  <select name="weekday">  <popeye:weekdays id="day">  <option value="<jsp:getProperty name="day" property="dayOfWeek"/>  "> <jsp:getProperty name="day" property="weekday"/> </popeye:weekdays>  </select> </form>   </body>  </html> 

Библиотека DATETIME также содержит множество других полезных тегов - посмотрите документацию, чтобы увидеть другие доступные функции.
Copyright Melonfire , 2000. Все права защищены.

У вас новое сообщение!

Теперь наш первоначальный тезис состоял в том, что библиотеки тегов позволят веб-дизайнерам, не знакомым с JSP, реализовать сложные функции на веб-странице. Хотя примеры, которые вы только что видели, были простыми и иллюстративными, они на самом деле не подтвердили этот тезис - в конце концов, разумно предположить, что любой компетентный веб-дизайнер будет знать, как манипулировать значениями даты и времени с помощью JavaScript, и не будет на самом деле для этого требуется библиотека тегов. Итак, давайте попробуем то, что большинство специалистов на стороне клиента не знает, как с этим справиться - доставка электронной почты.

Как правило, процесс создания электронной почты с веб-сайта обрабатывается с помощью серверного сценария - Perl-гуру открывают канал для sendmail, в то время как PHP-программисты достигают этой mail()функции. Это подразумевает предвидение PHP или Perl - не то, чего может ожидать новичок в веб-дизайнере. Какое решение предлагает JSP этой бедной душе?

Джакартская почтовая библиотека.

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

 <html>  <head>  </head>  <body>   <%@ taglib uri="jspmailer" prefix="jmail" %>   <jmail:mail server="mail.server.com" to="[email protected]"  from="[email protected]" subject="This stuff is pretty cool!">  <jmail:message> OK, you've convinced me - this tag library thing  is awesome! Where do I sign up? </jmail:message> <jmail:send/>  </jmail:mail>   </body>  </html> 

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

Апплет Antics

Вы уже видели , как JSP «действия» работу - в последней статье, например, мы продемонстрировали <jsp:useBean>и <jsp:setProperty>действия в сочетании с JavaBeans, в то время как <jsp:include>было показано в первой части этой серии статей. Тем не менее, мы упустили пару важных - и поэтому мы хотели бы познакомить вас с ними <jsp:plugin>, которые используются для включения Java-апплетов в веб-страницу.

<jsp:plugin>Директива заботится о создании всех HTML - код , необходимый для встраивания и активировать апплет Java. Рассмотрим следующий
пример:

 <html>  <head>  </head>  <body>   <jsp:plugin type="applet" code="NewsTicker.class"  name="newsticker" height="100" width="100">   <jsp:params>  <jsp:param name="x" value="10"/>  <jsp:param name="y" value="25"/>  <jsp:param name="cx" value="90"/>  <jsp:param name="cy" value="114"/>  <jsp:param name="bgcolor" value="102,102,153"/>  <jsp:param name="textcolor" value="0,0,0"/>  <jsp:param name="hilitecolor" value="255,0,0"/>  </jsp:params>   <jsp:fallback>Oops! Something bad happened and I can't display this  applet</jsp:fallback>   </jsp:plugin>   </body>  </html> 

Приведенный выше код устанавливает апплет, содержащийся в «NewsTicker.class», и передает ему набор параметров «имя-значение». <jsp:param>Тег используется , чтобы передать эти параметры апплета, в то время как <jsp:fallback>директива содержит текст сообщения об ошибке, в том случае, если апплет не может быть найден или отображаться.

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

 <html>  <head>  </head>  <body>   <OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"  width="100" height="100" codebase="http://java.sun.com/products/  plugin/1.2.2/jinstall-1_2_2-win.cab#V  ersion=1,2,2,0">  <PARAM name="java_code" value="NewsTicker.class">  <PARAM name="type" value="application/x-java-applet;">  <PARAM name="cy" value="114">  <PARAM name="cx" value="90">  <PARAM name="bgcolor" value="102,102,153">  <PARAM name="hilitecolor" value="255,0,0">  <PARAM name="y" value="25">  <PARAM name="x" value="10">  <PARAM name="textcolor" value="0,0,0">  <COMMENT>  <EMBED type="application/x-java-applet;"  width="100"  height="100"  pluginspage="http://java.sun.com/products/plugin/"  java_code="NewsTicker.class"  cy=114  cx=90  bgcolor=102,102,153  hilitecolor=255,0,0  y=25  x=10  textcolor=0,0,0  >  <NOEMBED>  </COMMENT>  Oops! Something bad happened and I can't display this applet  </NOEMBED></EMBED> </OBJECT>   </body>  </html> 

И наконец, <jsp:forward>директива используется для автоматического перенаправления клиентского запроса в другой документ. Следующий код автоматически перенаправляет клиента на скрипт «endzone.jsp».

 <jsp:forward page="endzone.jsp" /> 

Как и в предыдущем примере, дополнительные параметры могут быть переданы в новый скрипт через <jsp:param>. Например,

 <jsp:forward page="endzone.jsp">  <jsp:param name="user" value="joe" />  <jsp:param name="uid" value="653" />  <jsp:param name="gid" value="1220" />  </jsp:forward> 

И с этим, пришло время назвать это оберткой. Мы надеемся, что вам понравилось, и что это послужило хорошей отправной точкой для вашего вхождения в мир JSP.

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

До следующего раза ... будь здоров!

Примечание. Все примеры в этой статье были протестированы на Linux / i586 с Tomcat 3.2 и JServ 1.1. Примеры являются только иллюстративными и не предназначены для производственной среды. YMMV!
Copyright Melonfire , 2000. Все права защищены.