Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Часть 8 - JSP: расширяем возможности представления 
:(
    Опции темы
AntonSaburov
Дата 15.2.2007, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Штурман
****


Профиль
Группа: Модератор
Сообщений: 5658
Регистрация: 2.7.2002
Где: Санкт-Петербург

Репутация: 51
Всего: 118



JSP - расширяем возможности представления

Как мы уже видели в предыдущей статье, сервлеты позволяют нам получать запросы от клиента, совершать некоторую работу и выводить ее результаты на экран. До того момента, как надо осуществлять вывод на экран сервлет прекрасно работает. В него можно вставить достаточно сложную логику, сделать вызовы к базе данных и многое-многое другое, что необходимо для приложения. Но вот осуществлять вывод на экран внутри самого сервлета - очень неудобно. В нашем примере мы ограничились крайне простым решением. А что придется делать в случае вывода сложных дизайнерских идей? Вряд ли Web-дизайнер сможет понять, как надо осуществлять вывод внутри нашего сервлета. И когда он захочет осуществить свои дизайнерские идеи, то ему придется приходить к программисту и просить поменять код сервлета для того, чтобы изменить дизайн. Это над будет перекомпилировать, надо будет придумывать умные алгоритмы для вывода не только картинок, но и того же JavaScript. Просто кошмар.
Каждому здравомыслящему разработчику ясно, что надо придумать иное решение. Самое очевидное - придумать механизм, который разделил бы задачу на две составляющие: одна часть обрабатывает запрос, менять данные, собирает данные, укладывает это в некий пакет и передает второй части, которая делает только одно - показывает эти данные.
Так мы подошли к уже известному нам петтерну - Model-View-Controller (MVC). Для случая Web-приложений контроллером у нас становится сервлет, пакет данных, который мы сформировали - моделью. А вот на роль представления (View) прекрасно подходит JSP - Java Server Pages.
В этой статье мы сделаем общий обзор этой технологии. А <Отдел кадров> продолжим в следующей статье, где сможем сразу использовать знакомые технологии - сервлеты и JSP.

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

Код

<HTML>
   <HEAD>
      <TITLE> 
         Hello World Sample
      <TITLE>
   </HEAD>
   <BODY>
      <H1> 
         [И тут какие-то данные] 
      </H1>
   </BODY>
</HTML>


Чтобы вам не было скучно и для наглядности давайте изменим наш самый первый сервлет HelloWorldServlet из предыдущей статьи. Мы добавим ему возможность работать с параметром, который передадим с помощью URL. Его мы увидим чуть позже. А пока давайте посмотрим на несколько измененный сервлет HelloWorldServlet. Его задача сейчас очень проста - вывести приветствие "Hello, world !" в случае если не будет передано параметра name. Если же он передан, то приветствие несколько менятеся. Например при передаче параметра name=Anton сервлет должен вывести надпись "Hello, world. I'm Anton".
Ничего сложного в задаче нет и можно было бы решить ее без JSP, но для демонстрации нам подойдет.

Код

package students.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloWorldServlet extends HttpServlet
{
   public void doGet(HttpServletRequest req, HttpServletResponse resp)
       throws ServletException, IOException
   {
      getServletContext().getRequestDispatcher("/hello.jsp").forward(req, resp);
   }
}


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

Код

<html>
   <head>
      <title>
         Hello World Sample
      </title>
   </head>

   <body>
      <h1>
<%
   String name = request.getParameter("name");
   if(name== null || name.length() == 0) {
%>
         Hello, world !
<%
   } else {
%>
         Hello, world ! I'm <%= name %>
<%
   }
%>
      </h1>
   </body>
</html>


Как видите наш HTML-файл представляет из себя смесь тэгов для HTML и кода на JAVA. По сути JSP при первом обращении преобразуется в сервлет и работает уже по сути как сервлет. Только как видим страница хоть как-то напоминает HTML. Дизайнеру явно будет проще. Да и к тому же вам не надо перекомпилировать классы. Можно просто заменить JSP на более современную и она автоматичски будет скомпилирована заново.
Код JAVA заключается в угловые скобки со знаком процента "<%" и здесь вам можно написать любой код, который будет нужен.
Как видите наш код проверяет наличие параметра name в запросе (request.getParameter("name") ) и, если он существует, то выводится одна надпись. В противном случае мы увидим <укороченный> вариант надписи.
еще немного информации - JSP имеет в своем составе несколько предопределенных объектов. Это request, response, out, session, application, config, pageContext и page. Я дам коротенькую справку на них, возможно, что это пока будет не очень инетерсно да и не понятно. Но на всякий случай.

request
Это объект HttpServletRequest, связанный с запросом, который позволяет вам обращаться к параметрам запроса (через метод getParameter), типу запроса (GET, POST, HEAD, и т.д..), и входящим HTTP заголовкам (cookies, Referer, и т.д..). Проще говоря, request является подклассом ServletRequest и может отличаться от HttpServletRequest если используется протокол отличный от HTTP, что на практике практически никогда не встречается. 

response
Это объект типа HttpServletResponse, связанный с ответом на запрос клиента. Обратите внимание что, поскольку поток вывода (см. out далее) буферизован, можно изменять коды состояния HTTP и заголовки ответов, даже если это недопустимо в обычном сервлете, но лишь в том случае если какие-то данные вывода уже были отправлены клиенту. 

out
Это объект типа PrintWriter, используемый для отправки вывода клиенту. Однако, чтобы сделать объект response (см. предыдущий раздел) полезным, следует использовать буферизированный вариант PrintWriter - JspWriter. Помните что вы можете изменять размер буфера и даже отключить буферизацию, изменяя  значение атрибута buffer директивы page. Также обратите внимание что out используется практически исключительно скриплетами, поскольку выражения JSP автоматически помещаются в поток вывода, что избавляет от необходимости явного обращения к out. 

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

application
Это объект типа ServletContext полученный через использование метода getServletConfig().getContext(). 

config
Это объект типа ServletConfig для текущей страницы. 

pageContext
В JSP представлен новый класс PageContext для изолированного использования специфических особенностей сервера, таких как более эффективные JspWriters. Идея заключается в том, что если вы обращаетесь к ним через этот класс  а не непосредственно, ваш код может исполняться на "обычных" движках сервлет/JSP. 

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


Давайте все-таки посмотрим на наше творение в действии. Скомпилировать наш сервлет можно командой
Код

javac - cp .;servlet-api.jar students\web\*.java

После этого поместим наш класс HelloWorldServlet в каталог <TOMCAT_HOME>\webapps\studentsApp\WEB-INF\students\web\.
А файл hello.jsp в корневой каталог нашего приложения - <TOMCAT_HOME>\webapps\studentsApp
Предварительно можно переместить все содержимое из предыдущей статьи куда-нибудь (нам это еще может пригодиться)

Теперь наше дерево каталогов несколько проще (мы не используем некоторые классы)
Код

WEB-INF
   classes
      students
         web
            -HelloWorldServlet.class
   -web.xml
-hello.jsp


Запускаем Tomcat и потом попробуйте вызвать наше приложение по URL
Код

http://localhost:8080/studentsApp/hello


Если же хотите увидеть мое имя используйте такой URL
Код

http://localhost:8080/studentsApp/hello?name=Anton

Свое имя можно подставить потом smile


Custom Tag

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

Давайте рассмотрим несложный пример того, как можно написать и задействовать свой собственный тэг.
Для этого нам потребуется три шага:
1. Написать TLD-файл (Nag Library Definition) - файл описателя библиотеки тэгов.
2. Написать класс для реализации самого тэга
3. Исправить HTML-файл

Итак. Файл TLD имеет расширение .tld и обычно развертывается внутри каталога WEB-INF в каталоге вашего приложения. Хотя можно разместить и в другом. Если у вас много таких файлов, то для них можно предусмотреть отдельный каталог.

Вот наш вариант hello.tld
Код

<?xml version="1.0" encoding="ISO-8859-1" ?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
   <tlib-version>1.0</tlib-version>
   <jsp-version>1.2</jsp-version>
   <short-name>Sample Tag Library</short-name>
   <uri>/SimpleTagLibrary</uri>
   <description>
      Example of tag for HelloWorld
   </description>

   <tag>
      <name>hello</name>
      <tag-class>students.web.tag.HelloTag</tag-class>
      <body-content>empty</body-content>
      <description>
         Hello World Tag example
      </description>
      <attribute>
         <name>name</name>
         <required>false</required>
         <rtexprvalue>true</rtexprvalue>
      </attribute>
   </tag>
</taglib> 


Как вы наверно заметили из описания тэг - это класс HelloTag. Именно он отвечает за отображение информации. Давайте напишем его.

Код

package students.web.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.TagSupport;


public final class HelloTag extends TagSupport
{
   private String name = null;

   public int doStartTag() throws JspException
   {
      try {
         if(name == null) {
            pageContext.getOut().write("Hello, world!");
         }
         else {
            pageContext.getOut().write("Hello, world! I'm "+name);
         }
      }
      catch(IOException ioe) {
         throw new JspTagException(ioe.getMessage());
      }
      return SKIP_BODY;
   }

   public String getName()
   {
      return name;
   }

   public void setName(String name)
   {
      this.name = name;
   }

   public void release()
   {
      super.release();
      name = null;
   }



Для сборки нашего сервлета и нового тэга нам потребется более сложная строка
Код

javac -cp .;servlet-api.jar;jsp-api.jar students\web\*.java students\web\tag\*.java 

Новую библиотеку jsp-api.jar можно взять там же где и servlet_api.jar - в <TOMCAT_HOME>\common\lib
Теперь, чтобы подключить наш тэг к приложению необходимо прописать нашу библиотеку в файле web.xml

Код

<taglib>
   <taglib-uri>
      http://www.someurl.ru
   </taglib-uri>
   <taglib-location>
      /WEB-INF/hello.tld
   </taglib-location>
</taglib>


Ну и наконец нам нужен пример HTML-файла для использования нашего нового тэга

Код

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/WEB-INF/hello.tld" prefix="jstlpg" %>
<html>
   <head>
      <title>
         Hello World Sample
      </title>
   </head>

   <body>
      <h1>
         <jstlpg:hello name="<%= request.getParameter("name") %>" />
      </h1>
   </body>
</html>


Теперь нам осталось только разместить наши новый файлы в нужные каталоги и мы можем попробовать наши новые файлы.
Итак, вот наша новя структура каталогов:
Код

WEB-INF
   classes
      students
         web
            tag
               -HelloTag.class
            -HelloWorldServlet.class
   -web.xml
   -hello.tld
-hello.jsp


Теперь приведем исходники всех нужных нам файлов

HelloWorldServlet.java
Код

package students.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class HelloWorldServlet extends HttpServlet
{
  public void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException
  {
    getServletContext().getRequestDispatcher("/hello.jsp").forward(req, resp);
  }
}


HelloTag.java
Код

package students.web.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.TagSupport;


public final class HelloTag extends TagSupport
{
   private String name = null;

   public int doStartTag() throws JspException
   {
      try {
         if(name == null || name.length() == 0 ) {
            pageContext.getOut().write("Hello, world!");
         }
         else {
            pageContext.getOut().write("Hello, world! I'm "+name);
         }
      }
      catch(IOException ioe) {
         throw new JspTagException(ioe.getMessage());
      }
      return SKIP_BODY;
   }

   public String getName()
   {
      return name;
   }

   public void setName(String name)
   {
      this.name = name;
   }

   public void release()
   {
      super.release();
      name = null;
   }
}


hello.tld
Код

<?xml version="1.0" encoding="ISO-8859-1" ?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
   <tlib-version>1.0</tlib-version>
   <jsp-version>1.2</jsp-version>
   <short-name>Sample Tag Library</short-name>
   <uri>/SimpleTagLibrary</uri>
   <description>
      Example of tag for HelloWorld
   </description>

   <tag>
      <name>hello</name>
      <tag-class>students.web.tag.HelloTag</tag-class>
      <body-content>empty</body-content>
      <description>
         Hello World Tag example
      </description>
      <attribute>
         <name>name</name>
         <required>false</required>
         <rtexprvalue>true</rtexprvalue>
      </attribute>
   </tag>
</taglib>


web.xml
Код

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app>

    <display-name>Welcome to Students personnel</display-name>
    <description>
  Welcome to Students personnel
    </description>

    <servlet>
  <servlet-name>Hello</servlet-name>
  <servlet-class>students.web.HelloWorldServlet</servlet-class>
    </servlet>

    <servlet-mapping>
  <servlet-name>Hello</servlet-name>
  <url-pattern>/hello</url-pattern>
    </servlet-mapping>

    <taglib>
  <taglib-uri>
    http://www.someurl.ru
  </taglib-uri>
  <taglib-location>
    /WEB-INF/hello.tld
  </taglib-location>
    </taglib>

</web-app>


hello.jsp
Код

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/WEB-INF/hello.tld" prefix="jstlpg" %>
<html>
   <head>
      <title>
         Hello World Sample
      </title>
   </head>

   <body>
      <h1>
         <jstlpg:hello name="<%= request.getParameter("name") %>" />
      </h1>
   </body>
</html>
[/html]


Как видите, теперь наш HTML выглядит гораздо симпатичнее. Мы с вами попробовали очень простой тэг (правда мы его сами написали - и за это нам честь и хвала). Но как вы сами прекрасно понимаете большинство задач требует очень похожих тэгов. Отсюда предсказуемо появилась JSTL - JSP Standard Tag Library - библиотека стандартных тэгов JSP, в которой достаточно большое количество очень удобных тэгов, позволяющих делать списки, поля ввода, поля для ввода паролей и многое другое.
Конечно, многие моменты мы не рассмотрели, но думаю, что бует лучше отложить это до следующей статье, которая будет посвящена уже непосредственно нашему проекту Студенческий отдел кадров>. Там мы разработаем общий алгоритм, напишем необходимые сервлеты и JSP, в которых на примере будут показаны те моменты, которые мы не рассматривали здесь.

PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1159 ]   [ Использовано запросов: 23 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.