Избранное | Русский | Войти

Использование JSP

Несмотря на то что можно выводить HTML-код для пользовательского интерфейса напрямую из кода сервлета Java, его достаточно сложно поддерживать при усложнении HTML-кода. Лучше всего использовать систему шаблонов, в которой реализован интерфейс в виде отдельных файлов, содержащих заполнители, и представлена логика вставки полученных приложением данных. Для Java существует множество систем шаблонов. Все они будут работать с App Engine.

Чтобы реализовать пользовательский интерфейс для гостевой книги, в этом руководстве мы используем страницы JavaServer (JSP). Страницы JSP входят в стандарт сервлетов. App Engine автоматически компилирует файлы JSP в WAR приложения и устанавливает их соответствие с URL-путями.

Да здравствует JSP!

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

В каталоге war/ создайте файл guestbook.jsp следующего содержания:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.google.appengine.api.users.User" %>
<%@ page import="com.google.appengine.api.users.UserService" %>
<%@ page import="com.google.appengine.api.users.UserServiceFactory" %>

<html>
  <body>

<%
    UserService userService = UserServiceFactory.getUserService();
    User user = userService.getCurrentUser();
    if (user != null) {
%>
<p>Hello, <%= user.getNickname() %>! (You can
<a href="<%= userService.createLogoutURL(request.getRequestURI()) %>">sign out</a>.)</p>
<%
    } else {
%>
<p>Hello!
<a href="<%= userService.createLoginURL(request.getRequestURI()) %>">Sign in</a>
to include your name with greetings you post.</p>
<%
    }
%>

  </body>
</html>

По умолчанию для каждого файла в каталоге war/ и его подкаталогах (отличных от WEB-INF/) с названием, заканчивающимся на .jsp, автоматически устанавливается соответствие с URL-путем. URL-путь представляет путь к файлу .jsp, включая его название. Этой странице JSP будет автоматически сопоставлен URL /guestbook.jsp.

В приложении для гостевой книги мы хотим, чтобы это была его главная страница, к которой пользователи будут получать доступ при вызове URL /. Проще всего это сделать, объявив в файле web.xml, что страница guestbook.jsp является сервлетом "приветствия" для этого пути.

Измените файл war/WEB-INF/web.xml, заменив текущий элемент <welcome-file> в списке <welcome-file-list>. Не забудьте удалить из списка страницу index.html, поскольку статические файлы имеют приоритет над страницами JSP и сервлетами.

    <welcome-file-list>
        <welcome-file>guestbook.jsp</welcome-file>
    </welcome-file-list>

Совет. При использовании Eclipse редактор может открыть этот файл в режиме "Разработка". Чтобы изменить этот файл в виде XML, перейдите на вкладку "Источник" внизу фрейма.

Перезапустите сервер разработки. Посетите следующий URL-адрес.

Приложение показывает содержание файла guestbook.jsp, включая псевдоним пользователя, если он выполнил вход.

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

При добавлении приложения в App Engine SDK компилирует все страницы JSP в байтовый код и добавляет только его. При выполнении приложения на App Engine он используют скомпилированные классы JSP.

Форма гостевой книги

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

Измените файл guestbook.jsp, добавив следующие строки сразу над закрывающим тегом </body>:

  ...

  <form action="/sign" method="post">
    <div><textarea name="content" rows="3" cols="60"></textarea></div>
    <div><input type="submit" value="Post Greeting" /></div>
  </form>

  </body>
</html>

Создайте в пакете guestbook класс SignGuestbookServlet. (Если не используете Eclipse, создайте файл SignGuestbookServlet.java в каталоге src/guestbook/.) Поместите в исходный файл следующее содержание:

package guestbook;

import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.http.*;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

public class SignGuestbookServlet extends HttpServlet {
    private static final Logger log = Logger.getLogger(SignGuestbookServlet.class.getName());

    public void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws IOException {
        UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();

        String content = req.getParameter("content");
        if (content == null) {
            content = "(No greeting)";
        }
        if (user != null) {
            log.info("Greeting posted by user " + user.getNickname() + ": " + content);
        } else {
            log.info("Greeting posted anonymously: " + content);
        }
        resp.sendRedirect("/intl/ru/guestbook.jsp");
    }
}

Чтобы объявить сервлет SignGuestbookServlet и установить соответствие с URL /sign, измените файл war/WEB-INF/web.xml, добавив следующие строки:

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    ...

    <servlet>
        <servlet-name>sign</servlet-name>
        <servlet-class>guestbook.SignGuestbookServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sign</servlet-name>
        <url-pattern>/sign</url-pattern>
    </servlet-mapping>

    ...
</web-app>

Для записи сообщений в журнал новый сервлет использует класс java.util.logging.Logger. Можно управлять поведением этого класса с помощью файла logging.properties и системными свойствами, указанными в файле приложения appengine-web.xml. При использовании Eclipse приложение создается с версией этого файла по умолчанию в каталоге приложения src/ и соответствующим системным свойством.

В противном случае нужно настроить файл конфигурации Logger вручную. Скопируйте пример файла из SDK appengine-java-sdk/config/user/logging.properties в каталог приложения war/WEB-INF/. Затем измените файл приложения war/WEB-INF/appengine-web.xml следующим образом:

<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    ...

    <system-properties>
        <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
    </system-properties>

</appengine-web-app>

Сервлет записывает сообщения с уровнем INFO (используя метод log.info()). По умолчанию уровень сообщений WARNING, который имеет приоритет над сообщениями INFO из выходного потока. Чтобы изменить этот уровень для всех классов в пакете guestbook, отредактируйте файл logging.properties, добавив запись для guestbook.level следующим образом:

.level = WARNING
guestbook.level = INFO

...

Совет. Когда при выполнении на App Engine приложение записывает сообщение с помощью API java.util.logging.Logger, App Engine записывает сообщения и делает их доступными для просмотра в Консоли администрирования и загрузки с помощью инструмента AppCfg. Консоль администрирования позволяет просматривать сообщения по уровню серьезности.

Повторно соберите и перезапустите приложение, затем проверьте http://localhost:8080/. Отобразится форма. Введите текст и отправьте ее. Браузер отправит форму приложению, а затем перенаправит обратно в пустую форму. Введенные данные пожелания будут записаны в консоль сервером.

Далее...

У нас есть пользовательский интерфейс, который просит пользователя ввести пожелание. Теперь нам нужен способ сохранения отправленных пользователями пожеланий и их показа другим посетителям. Для этого нам понадобится хранилище данных App Engine.

Самое время перейти к статье Использование хранилища данных с JDO.