Пример JSP учебника для начинающих

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

JSP Учебник по Примерам

В этом учебнике по примеру JSP мы рассмотрим основы JSP, преимущества JSP перед Servlets, жизненный цикл JSP, интерфейсы и классы API JSP, и где мы можем разместить файлы JSP в веб-приложении. Мы также рассмотрим комментарии JSP, Scriptlets, Директивы, Выражение, Объявление и атрибуты JSP в краткой детали. Некоторые из этих тем очень важны, и мы рассмотрим их более подробно в будущих сообщениях.

JSP Учебник

  1. Что такое JSP и зачем нам нужен JSP?
  2. Преимущества JSP перед Servlets?
  3. Жизненный цикл страницы JSP
  4. Методы жизненного цикла JSP
  5. Простой пример JSP с использованием Eclipse и Tomcat
  6. Местоположение файлов JSP в файле WAR веб-приложения
  7. Интерфейсы и классы API JSP
  1. Комментарии JSP

  2. Скриптлеты JSP

  3. Выражения JSP

  4. Директивы JSP

  5. Объявления JSP

  6. Исходный код преобразованного сервлета JSP и расположение файла класса в Tomcat

  7. Параметры инициализации JSP

  8. Переопределение метода init() JSP

  9. Атрибуты в JSP

  10. Что такое JSP и зачем нам нужен JSP?

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

  11. Преимущества JSP перед сервлетами?

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

    Жизненный цикл JSP также управляется контейнером. Обычно каждый веб-контейнер, содержащий контейнер сервлетов, также содержит контейнер JSP для управления JSP-страницами. Фазы жизненного цикла JSP-страницы:

    • Перевод – JSP-страницы не выглядят как обычные классы Java; фактически контейнер JSP анализирует страницы JSP и транслирует их для создания соответствующего исходного кода сервлета. Если имя файла JSP – home.jsp, обычно оно называется home_jsp.java.
    • Компиляция – Если перевод успешен, то контейнер компилирует сгенерированный исходный файл сервлета для создания файла класса.
    • Загрузка класса – После того как JSP скомпилирована в класс сервлета, ее жизненный цикл аналогичен сервлету, и она загружается в память.
    • Создание экземпляра – После загрузки класса JSP в память его объект создается контейнером.
    • Инициализация – Затем класс JSP инициализируется, и он преобразуется из обычного класса в сервлет. После инициализации объекты ServletConfig и ServletContext становятся доступными для класса JSP.
    • Обработка запроса – Для каждого запроса клиента создается новый поток с объектами ServletRequest и ServletResponse для обработки и генерации HTML-ответа.
    • Уничтожение – Последняя фаза жизненного цикла JSP, когда она выгружается из памяти.
  13. Методы жизненного цикла JSP

    Методы жизненного цикла JSP:

    1. jspInit() объявлен в интерфейсе JspPage. Этот метод вызывается только один раз в жизненном цикле JSP для инициализации параметров конфигурации.
    2. _jspService(HttpServletRequest request, HttpServletResponse response) объявлен в интерфейсе HttpJspPage и отвечает за обработку запросов клиентов.
    3. jspDestroy() объявлен в интерфейсе JspPage для выгрузки JSP из памяти.
  14. Простой пример JSP с Eclipse и Tomcat

We can use Eclipse IDE for building dynamic web project with JSPs and use Tomcat to run it. Please read [Java Web Applications](/community/tutorials/java-web-application-tutorial-for-beginners#first-web-app-servlet) tutorial to learn how can we easily create JSPs in Eclipse and run it in tomcat. A simple JSP example page example is: `home.jsp`

```
<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>First JSP</title>
</head>
<%@ page import="java.util.Date" %>
<body>
<h3>Hi Pankaj</h3><br>
<strong>Current Time is</strong>: <%=new Date() %>

</body>
</html>
```

If you have a simple JSP that uses only JRE classes, we are not required to put it as WAR file. Just create a directory in the tomcat webapps folder and place your JSP file in the newly created directory. For example, if your JSP is located at apache-`tomcat/webapps/test/home.jsp`, then you can access it in browser with URL `https://localhost:8080/test/home.jsp`. If your host and port is different, then you need to make changes in URL accordingly.
  1. Местоположение файлов JSP в WAR-файле веб-приложения

We can place JSP files at any location in the WAR file, however if we put it inside the WEB-INF directory, we wont be able to access it directly from client. We can configure JSP just like servlets in web.xml, for example if I have a JSP example page like below inside WEB-INF directory: `test.jsp`

```
<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Test JSP</title>
</head>
<body>
Test JSP Page inside WEB-INF folder.<br>
Init Param "test" value =<%=config.getInitParameter("test") %><br>
HashCode of this object=<%=this.hashCode() %>
</body>
</html>
```

And I configure it in web.xml configuration as:

```
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>FirstJSP</display-name>
  
  <servlet>
  <servlet-name>Test</servlet-name>
  <jsp-file>/WEB-INF/test.jsp</jsp-file>
  <init-param>
  	<param-name>test</param-name>
  	<param-value>Test Value</param-value>
  </init-param>
  </servlet>
  
  <servlet-mapping>
  <servlet-name>Test</servlet-name>
  <url-pattern>/Test.do</url-pattern>
  </servlet-mapping>
  
  <servlet>
  <servlet-name>Test1</servlet-name>
  <jsp-file>/WEB-INF/test.jsp</jsp-file>
  </servlet>
  
  <servlet-mapping>
  <servlet-name>Test1</servlet-name>
  <url-pattern>/Test1.do</url-pattern>
  </servlet-mapping>
</web-app>
```

Then I can access it with both the URLs https://localhost:8080/FirstJSP/Test.do and https://localhost:8080/FirstJSP/Test1.do Notice that container will create two instances in this case and both will have their own servlet config objects, you can confirm this by visiting these URLs in browser. For Test.do URI, you will get response like below.

```
Test JSP Page inside WEB-INF folder.
Init Param "test" value =Test Value
HashCode of this object=1839060256
```

For Test1.do URI, you will get response like below.

```
Test JSP Page inside WEB-INF folder.
Init Param "test" value =null
HashCode of this object=38139054
```

Notice the init param value in second case is null because it's not defined for the second servlet, also notice the hashcode is different. If you will make further requests, the hashcode value will not change because the requests are processed by spawning a new thread by the container. Did you noticed the use of **config** variable in above JSP example but there is no variable declared, it's because its one of the 9 implicit objects available in JSP page, read more about them at [**JSP Implicit Objects**](/community/tutorials/jsp-implicit-objects "JSP Implicit Objects with Examples").
  1. Интерфейсы и классы JSP API

All the core JSP interfaces and classes are defined in `javax.servlet.jsp` package. Expression Language API interfaces are classes are part of `javax.servlet.jsp.el` package. JSP Tag Libraries interfaces and classes are defined in `javax.servlet.jsp.tagext` package. Here we will look into interfaces and classes of Core JSP API.
  • Интерфейс JspPage

    Интерфейс JspPage расширяет интерфейс Servlet и объявляет методы жизненного цикла jspInit() и jspDestroy() для страниц JSP.

  • Интерфейс HttpJspPage

    Интерфейс HttpJspPage описывает взаимодействие, которому должен удовлетворять класс реализации страницы JSP при использовании протокола HTTP. Этот интерфейс объявляет метод службы страницы JSP для протокола HTTP следующим образом: public void _jspService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException.

  • Абстрактный класс JspWriter

    Аналог PrintWriter в сервлетах с дополнительной поддержкой буферизации. Это одна из неявных переменных на странице JSP с именем “out”. Этот класс расширяет java.io.Writer, и контейнер предоставляет свою собственную реализацию этого абстрактного класса и использует его при переводе страницы JSP в сервлет. Мы можем получить его объект с помощью метода PageContext.getOut(). Конкретный класс Apache Tomcat для JspWriter – org.apache.jasper.runtime.JspWriterImpl.

  • Абстрактный класс JspContext

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

  • Абстрактный класс PageContext

    PageContext расширяет JspContext для предоставления полезной контекстной информации при использовании JSP для веб-приложений. Экземпляр PageContext предоставляет доступ ко всем пространствам имен, связанным с страницей JSP, предоставляет доступ к нескольким атрибутам страницы, а также слой над деталями реализации. Неявные объекты добавляются в pageContext автоматически.

  • Абстрактный класс JspFactory

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

  • Абстрактный класс JspEngineInfo

    JspEngineInfo – это абстрактный класс, который предоставляет информацию о текущем движке JSP.

  • Класс ErrorData final

    Содержит информацию об ошибке для страниц ошибок.

  • Класс JspException

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

  • Класс JspTagException

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

  • Класс SkipPageException

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

  1. Комментарии JSP

Since JSP is built on top of HTML, we can write comments in JSP file like html comments as `<-- This is HTML Comment -->` These comments are sent to the client and we can look it with view source option of browsers. We can put comments in JSP files as: `<%-- This is JSP Comment--%>` This comment is suitable for developers to provide code level comments because these are not sent in the client response.
  1. Скриптлеты JSP

Scriptlet tags are the easiest way to put java code in a JSP page. A scriptlet tag starts with `<%` and ends with `%>`. Any code written inside the scriptlet tags go into the `_jspService()` method. For example:

```
<%
Date d = new Date();
System.out.println("Current Date="+d);
%>
```
  1. Выражения JSP

Since most of the times we print dynamic data in JSP page using _out.print()_ method, there is a shortcut to do this through JSP Expressions. JSP Expression starts with `<%=` and ends with `%>`. `<% out.print("Pankaj"); %>` can be written using JSP Expression as `<%= "Pankaj" %>` Notice that anything between `<%= %>` is sent as parameter to `out.print()` method. Also notice that scriptlets can contain multiple java statements and always ends with semicolon (;) but expression doesn't end with semicolon.
  1. Директивы JSP

JSP Directives are used to give special instructions to the container while JSP page is getting translated to servlet source code. JSP directives starts with `<%@` and ends with `%>` For example, in above JSP Example, I am using _page_ directive to to instruct container JSP translator to import the Date class.
  1. Объявление JSP

JSP Declarations are used to declare member methods and variables of servlet class. JSP Declarations starts with `<%!` and ends with `%>`. For example we can create an int variable in JSP at class level as `<%! public static int count=0; %>`
  1. Преобразованный исходный код сервлета JSP и местоположение файла класса в Tomcat

Once JSP files are translated to Servlet source code, the source code (.java) and compiled classes both are place in **Tomcat/work/Catalina/localhost/FirstJSP/org/apache/jsp** directory. If the JSP files are inside other directories of application, the directory structure is maintained. For JSPs inside WEB-INF directory, its source and class files are inside **Tomcat/work/Catalina/localhost/FirstJSP/org/apache/jsp/WEB\_002dINF** directory. Here is the source code generated for above test.jsp page. `test_jsp.java`

```
/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/7.0.32
 * Generated at: 2013-08-21 03:40:59 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp.WEB_002dINF;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
  }

  public void _jspDestroy() {
  }

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
        throws java.io.IOException, javax.servlet.ServletException {

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html; charset=US-ASCII");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\n");
      out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"https://www.w3.org/TR/html4/loose.dtd\">\n");
      out.write("<html>\n");
      out.write("<head>\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">\n");
      out.write("<title>Test JSP</title>\n");
      out.write("</head>\n");
      out.write("<body>\n");
      out.write("Test JSP Page inside WEB-INF folder.<br>\n");
      out.write("Init Param \"test\" value =");
      out.print(config.getInitParameter("test") );
      out.write("<br>\n");
      out.write("HashCode of this object=");
      out.print(this.hashCode() );
      out.write("\n");
      out.write("</body>\n");
      out.write("</html>");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}
```

Notice following points in above servlet code;
-   The package of class starts with org.apache.jsp and if JSPs are inside other folders, it includes directory hierarchy too. Usually we dont care about it.
-   The generates servlet class is final and can't be extended.
-   It extends `org.apache.jasper.runtime.HttpJspBase` that is similar to HttpServlet except that it's internal to Tomcat JSP Translator implementation. HttpJspBase extends HttpServlet and implements HttpJspPage interface.
-   Notice the local variables at the start of \_jspService() method implementation, they are automatically added by JSP translator and available for use in service methods, i.e in scriptlets.As a java programmer, sometimes it helps to look into the generated source for debugging purposes.
  1. Параметры инициализации JSP

We can define init parameters for the JSP page as shown in above example and we can retrieve them in JSP using **config** implicit object, we will look into implicit objects in JSP in more detail in future posts.
  1. Переопределение метода init() JSP

We can override JSP init method for creating resources to be used by JSP service() method using JSP Declaration tags, we can override jspInit() and jspDestroy() or any other methods also. However we should never override \_jspService() method because anything we write in JSP goes into service method.
  1. Атрибуты в JSP

Apart from standard servlet attributes with request, session and context scope, in JSP we have another scope for attributes, i.e Page Scope that we can get from pageContext object. We will look it's importance in custom tags tutorial. For normal JSP programming, we don't need to worry about page scope.

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

Source:
https://www.digitalocean.com/community/tutorials/jsp-example-tutorial-for-beginners