Перейти к основному содержимому

Руководство по страницам JavaServer (JSP)

· 12 мин. чтения

Задача: Наибольшая подстрока без повторений

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

ANDROMEDA 42

Оглавление

1. Обзор

JavaServer Pages (JSP) позволяет вводить динамическое содержимое в статическое содержимое с помощью Java и сервлетов Java . Мы можем делать запросы к сервлету Java, выполнять соответствующую логику и отображать определенное представление на стороне сервера для использования на стороне клиента . В этой статье представлен подробный обзор страниц JavaServer с использованием Java 8 и Jave 7 EE.

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

2. Страницы JavaServer

Страницы JavaServer (JSP) позволяли передавать или помещать в представление .jsp специфичные для Java данные и использовать их на стороне клиента.

Файлы JSP по сути представляют собой файлы .html с дополнительным синтаксисом и парой незначительных первоначальных отличий:

  1. суффикс .html заменяется на .jsp (он считается типом файла .jsp) и
  2. в начало элементов разметки .html добавляется следующий тег:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

Давайте рассмотрим некоторые ключевые концепции JSP.

2.1. JSP-синтаксис

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

<% Java code here %>

Второй метод специфичен для XML:

<jsp:scriptlet>
Java code here
</jsp:scriptlet>

Важно отметить, что можно использовать условную логику на стороне клиента с JSP, используя предложения if , then и else , а затем заключая соответствующие блоки разметки в эти скобки.

<% if (doodad) {%>
<div>Doodad!</div>
<% } else { %>
<p>Hello!</p>
<% } %>

Например, если doodad имеет значение true, мы отобразим первый элемент div , иначе мы отобразим второй элемент p !

2.2. Статическое и динамическое содержимое

Статическое веб-содержимое — это фиксированные активы, которые используются независимо от запросов RESTful, SOAP, HTTP, HTTPS или другой информации, предоставленной пользователем.

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

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

Сервер (сервлет) управляет динамическим содержимым, а клиент (фактическая страница .jsp) является статическим контекстом, в который вводится динамическое содержимое.

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

2.3. Неявные объекты

Неявные объекты генерируются механизмом JSP автоматически во время компиляции .

Неявные объекты включают объекты HttpRequest и HttpResponse и предоставляют различные серверные функции для использования в вашем сервлете и для взаимодействия с вашим .jsp! Вот список неявных объектов , которые создаются:

запрос

запроса принадлежит классу javax.servlet.http.HttpServletRequest . Объект запроса предоставляет все данные, введенные пользователем, и делает их доступными на стороне сервера.

response

response принадлежит классу javax.servlet.http.HttpServletResponse и определяет, что передается на клиентскую сторону после выполнения запроса .

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

Пример ниже демонстрирует очень простой, неполный метод сервлета для обработки запросов GET. Я опустил большую часть деталей, чтобы мы могли сосредоточиться на том, как использовать объекты запроса и ответа :

protected void doGet(HttpServletRequest request, 
HttpServletResponse response) throws ServletException, IOException {
String message = request.getParameter("message");
response.setContentType("text/html");
. . .
}

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

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

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

out принадлежит классу javax.servlet.jsp.JspWriter

и используется для записи содержимого клиенту. ``

Существует как минимум два способа печати на JSP-странице, и здесь стоит обсудить оба. out создается автоматически и позволяет вам писать в память, а затем в объект ответа :

out.print(“hello”);
out.println(“world”);

Вот и все!

Второй подход может быть более производительным, так как позволяет вам писать непосредственно в объект ответа ! Здесь мы используем PrintWriter :

PrintWriter out = response.getWriter();
out.println("Hello World");

2.4. Другие неявные объекты

Вот некоторые другие неявные объекты , которые также полезно знать!

сеанс

сеанса принадлежит классу javax.servlet.http.HttpSession , который поддерживает данные пользователя в течение всего сеанса.

приложение

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

исключение

исключение принадлежит классу javax.servlet.jsp.JspException используется для отображения сообщений об ошибках на страницах JSP, которые имеют тег <%@ page isErrorPage="true" %> .

страница

page принадлежит классу java.lang.Object позволяет получить доступ или сослаться на текущую информацию о сервлете.

pageContext

pageContext принадлежит классу javax.servlet.jsp.PageContext по умолчанию соответствует области действия страницы, но может использоваться для доступа к атрибутам запроса , приложения и сеанса .

config

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

Теперь, когда мы рассмотрели неявные объекты , предоставляемые JSP, давайте обратимся к директивам , которые позволяют страницам .jsp (косвенно) обращаться к некоторым из этих объектов.

2.5. Директивы

JSP предоставляет стандартные директивы, которые можно использовать для указания основных функций наших файлов JSP. Директивы JSP состоят из двух частей: (1) сама директива и (2) атрибут этой директивы, которому присваивается значение.

Три вида директив, на которые можно ссылаться с помощью тегов директив: <%@ page … %> , которая определяет зависимости и атрибуты JSP, включая тип контента и язык , <%@ include … %> , которая указывает импорт или файл, который будет использоваться. и <%@ taglib …%> , который указывает библиотеку тегов, определяющую пользовательские действия, которые будут использоваться страницей.

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

И мы можем сделать это с помощью XML следующим образом: <jsp:directive.page attribute="value" />

2.6. Атрибуты директивы страницы

В директиве страницы можно объявить множество атрибутов:

autoFlush <%@ page autoFlush="false" %> **

**

autoFlush управляет выводом буфера, очищая его при достижении размера буфера. Значение по умолчанию — true .

буфер <%@ page buffer="19kb" %> **

**

buffer устанавливает размер буфера, используемого нашей JSP-страницей. Значение по умолчанию — 8 КБ.

errorPage <%@ страница errorPage="errHandler.jsp" %> **

**

errorPage указывает страницу JSP как страницу ошибки.

extends <%@ page extends="org.apache.jasper.runtime.HttpJspBase" %> **

**

extends указывает суперкласс соответствующего кода сервлета.

info <%@ page info=”Это мой JSP!” %>

info используется для установки текстового описания JSP.

isELIGnored <%@ page isELIGnored="true" %>

isELIGnored указывает, будет ли страница игнорировать язык выражений (EL) в JSP. EL позволяет уровню представления взаимодействовать с управляемыми компонентами Java и делает это с использованием синтаксиса ${…} , и хотя мы не будем вдаваться в подробности EL здесь, ниже приведено несколько примеров, которых достаточно для создания нашего примера JSP. приложение! Значение по умолчанию для isELIGnoredfalse .

isErrorPage <%@ page isErrorPage="true" %>

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

isThreadSafe <%@ страница isThreadSafe="false" %>

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

отключить эту функцию.

язык <%@ page language="java" %>

язык определяет, какой язык сценариев использовать в JSP. Значение по умолчанию — Java .

сеанс <%@ page session="value"%>

session определяет, следует ли поддерживать сеанс HTTP. По умолчанию он равен true и принимает значения true или false .

trimDirectiveWhitespaces <%@ page trimDirectiveWhitespaces = «true» %>

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

3. Три примера

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

Существует три основных способа внедрить Java в .jsp, и мы рассмотрим каждый из этих способов ниже, используя встроенные функции в Java 8 и Jakarta EE.

Во-первых, мы отобразим нашу разметку на стороне сервера для отображения на стороне клиента. Во- вторых, мы рассмотрим, как добавить код Java непосредственно в наш файл .jsp независимо от объектов запроса и ответа javax.servlet.http .

В- третьих, мы покажем, как перенаправить HttpServletRequest на конкретный .jsp и привязать к нему Java, обработанный на стороне сервера.

Давайте настроим наш проект в Eclipse, используя тип File/New/Project/Web/Dynamic web project/ для размещения в Tomcat! Вы должны увидеть после создания проекта:

|-project
|- WebContent
|- META-INF
|- MANIFEST.MF
|- WEB-INF
|- lib
|- src

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

|-project
|- WebContent
|- META-INF
|- MANIFEST.MF
|- WEB-INF
|-lib
*-web.xml
|- ExampleTree.jsp
|- ExampleTwo.jsp
*- index.jsp
|- src
|- com
|- foreach
*- ExampleOne.java
*- ExampleThree.java

Давайте настроим index.jsp , который будет отображаться при доступе к контексту URL в Tomcat 8:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP Examples</title>
</head>
<body>
<h1>Simple JSP Examples</h1>
<p>Invoke HTML rendered by Servlet: <a href="ExampleOne" target="_blank">here</a></p>
<p>Java in static page: <a href="ExampleTwo.jsp" target="_blank">here</a></p>
<p>Java injected by Servlet: <a href="ExampleThree?message=hello!" target="_blank">here</a></p>
</body>
</html>

Есть три a , каждая из которых ссылается на один из примеров, которые мы рассмотрим ниже в разделах с 4.1 по 4.4.

Нам также нужно убедиться, что у нас настроен наш web.xml :

<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>ExampleOne</servlet-name>
<servlet-class>com.foreach.ExampleOne</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ExampleOne</servlet-name>
<url-pattern>/ExampleOne</url-pattern>
</servlet-mapping>

Основное замечание здесь — как правильно сопоставить каждый из наших сервлетов с конкретным сопоставлением сервлетов. При этом каждый сервлет связывается с определенной конечной точкой, где он может быть использован! Теперь мы пройдемся по всем остальным файлам ниже!

3.1. HTML, отображаемый в сервлете

В этом примере мы фактически пропустим создание файла .jsp!

Вместо этого мы создадим строковое представление нашей разметки, а затем запишем его в ответ GET с помощью PrintWriter после того, как сервлет ExampleOne получит запрос GET:

public class ExampleOne extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println(
"<!DOCTYPE html><html>" +
"<head>" +
"<meta charset=\"UTF-8\" />" +
"<title>HTML Rendered by Servlet</title>" +
"</head>" +
"<body>" +
"<h1>HTML Rendered by Servlet</h1></br>" +
"<p>This page was rendered by the ExampleOne Servlet!</p>" +
"</body>" +
"</html>"
);
}
}

Что мы здесь делаем, так это внедряем нашу разметку через обработку запросов сервлета напрямую. Вместо тега JSP мы генерируем наш HTML вместе со всеми специфичными для Java данными, которые нужно вставить, исключительно на стороне сервера без статического JSP!

Ранее мы рассмотрели объект out, который является функцией JspWriter .

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

JspWriter фактически буферизует строку для записи в память, которая затем записывается в объекты ответа после очистки буфера в памяти.

PrintWriter уже подключен к объекту ответа . По этим причинам я предпочел писать непосредственно в объект ответа в примерах выше и ниже.

3.2. Java в статическом содержимом JSP

Здесь мы создаем файл JSP с именем ExampleTwo.jsp с тегом JSP. Как видно выше, это позволяет добавлять Java непосредственно в нашу разметку. Здесь мы случайным образом печатаем элемент String[] :

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<head>
<title>Java in Static Page Example</title>
</head>
<body>
<h1>Java in Static Page Example</h1>
<%
String[] arr = {"What's up?", "Hello", "It's a nice day today!"};
String greetings = arr[(int)(Math.random() * arr.length)];
%>
<p><%= greetings %></p>
</body>
</html>

Выше вы увидите это объявление переменной в объектах тегов JSP: тип variableName и инициализация , как в обычной Java.

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

3.3. JSP с пересылкой

Теперь перейдем к нашему последнему и наиболее сложному примеру! Здесь мы собираемся использовать аннотацию @WebServlet в ExampleThree, что устраняет необходимость сопоставления сервлетов в server.xml .

@WebServlet(
name = "ExampleThree",
description = "JSP Servlet With Annotations",
urlPatterns = {"/ExampleThree"}
)
public class ExampleThree extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String message = request.getParameter("message");
request.setAttribute("text", message);
request.getRequestDispatcher("/ExampleThree.jsp").forward(request, response);
}
}

ExampleThree принимает параметр URL, переданный как message , связывает этот параметр с объектом запроса , а затем перенаправляет этот объект запроса в ExampleThree.jsp .

Таким образом, мы не только добились действительно динамичного веб- интерфейса, но и сделали это в приложении, содержащем несколько файлов .jsp.

getRequestDispatcher().forward() — это простой способ убедиться, что отображается правильная страница .jsp.

Все данные, привязанные к объекту запроса , отправленному его (файлу .jsp), будут отображаться! Вот как мы обрабатываем последнюю часть:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<head>
<title>Java Binding Example</title>
</head>
<body>
<h1>Bound Value</h1>
<p>You said: ${text}</p>
</body>
</html>

Обратите внимание на тег JSP, добавленный вверху файла ExampleThree.jsp . Вы заметите, что я поменял теги JSP здесь. Я использую язык выражений (о котором я упоминал ранее) для отображения нашего заданного параметра (который связан как ${text} )!

3.4. Попробуйте!

Теперь мы экспортируем наше приложение в .war для запуска и размещения в Tomcat 8! Найдите свой server.xml , и мы обновим наш контекст до:

<Context path="/spring-mvc-xml" docBase="${catalina.home}/webapps/spring-mvc-xml">
</Context>

Это позволит нам получить доступ к нашим сервлетам и JSP на локальном хосте: 8080/spring-mvc-xml/jsp/index.jsp ! Возьмите рабочую копию по адресу: GitHub . Поздравляю!

4. Вывод

Мы охватили довольно много земли! Мы узнали о том, что такое JavaServer Pages, для чего они были введены, об их жизненном цикле, о том, как их создавать, и, наконец, о нескольких различных способах их реализации!

На этом введение в JSP завершено! Будьте здоровы и кодируйте!