Jetty Tutorial
Jetty is a web server which can be easily embedded into Java applications. It has the following core components:
2. Using Jetty as standalone server
2.1. Installation of a standalone Jetty
Download Jetty from https://www.eclipse.org/jetty/download.html and extract the zip file somewhere to your filesystem.
This update site contains also a Eclipse p2 update site, in case you want to use Jetty in an OSGi environment.
2.2. Start Jetty standalone from the JAR file
To start Jetty, switch on the command line to the installation directory and issue the following command.
Introduction to Jetty
This is an introductory Jetty tutorial. The purpose of this tutorial is to get you started with Jetty. The tutorial has been created and tested on Linux. This tutorial covers Jetty version 11.
Advertisements About Jetty
Jetty is an open source project providing an HTTP server, an HTTP client, and a Java servlet container. The project is a part of the Eclipse Foundation. Jetty is a mature project, which started in 1995. Jetty can be easily embedded in devices, tools, frameworks, application servers, and clusters.
- SPDY
- WebSockets
- JNDI
- JAAS
- OSGi
- AJP
- JMX
Installing Jetty
In this article we work on a local computer. Detailed instructions to install Jetty on a remote server are provided in a separate chapter. First, we download Jetty from the Eclipse’s download page to a directory of our choice.
We unpack the compressed file.
We list the contents of the directory. The bin directory contains utility scripts to help run Jetty on Unix systems. The lib directory contains all JAR files necessary to run Jetty. The modules directory has module definitions where a module is a configuration file that includes all the libraries, dependencies, XML and template INI files for a Jetty feature. The start.jar is used to invoke Jetty.
A JETTY_HOME environment variable is created.
Advertisements Running Jetty
To run the Jetty server, we use the start.jar file.
We create start.d directory which contains the configuration of the server.
We run the server passing the start.jar file to the java command. The start.jar builds a classpath and executes a main java class with a classloader built from that classpath. By default the start.jar mechanism is configured to start the Jetty server, but it can be configured to start any Java main class.
We can now navigate a browser at this server at http://localhost:8080.
We use a command line tool curl to do the HTTP request. The server returns a 404 error—there is no application in the webapps directory yet.
JETTY_HOME & JETTY_BASE
Starting with Jetty 9.1, it is possible to maintain a separation between the binary installation of the standalone Jetty called Jetty home, and the customizations for a specific environment called Jetty base. Jetty home is the location for the Jetty distribution binaries, default XML configurations, and default module definitions. Jetty base is the location for configurations and customizations to the Jetty distribution.
We create a my-base directory which will be our Jetty base.
A JETTY_BASE environment variable is created. Jetty determines the Jetty home and Jetty base locations either from environment variables or from properties.
Three important items of a Jetty base are the start.d configuration directory, the start.ini configuration file, and the webapps directory. We use the start.jar to enable necessary modules of Jetty. The —add-module option adds the given module to the list of modules enabled at when Jetty starts.
The start.ini file is created and the deploy module is added to it. Also the webapps directory is created.
The http module configuration named http.ini is created in the start.d directory.
At this moment we have this content in our Jetty base directory. Actually, we have enabled more than two modules—modules may have dependent modules and these were enabled as well. For instance, by enabling the http module we have activated the server module as well.
The —list-modules option list all modules, both active and inactive. At the end of the output we have a tree of active modules.
It is recommended to sit in the Jetty base directory and to start the server by referencing the start.jar remotely.
First web application
We create and deploy our first web application with Jetty. The application will display a simple JSP page. We create a Jetty base from scratch to enable running JSP pages.
Простая веб-служба со встроенным Jetty
Развитие информационных технологий все более и более вовлекает использование инфраструктуры Интернет. Распределенные и мобильные приложения все чаще используют обмен информацией по протоколу HTTP. При этом архитектура Клиент-Сервер остается самой распространённой и простой для освоения, создания и эксплуатации. Принцип архитектуры Клиент-Сервер прост — сервер предоставляет ресурс, а клиент использует этот ресурс.
Данная статья представляет собой попытку понятного описания создания простой веб-службы. Простой, практичный и детально описанный пример часто приносит больше пользы в изучении технологии нежели усердное чтение литературы. В статье рассматривается создание веб-службы простого калькулятора на основе REST, JSON, используя Eclipse и встроенной сервер Jetty.
Задача
Рассмотрим создание калькулятора как веб-службу, реализующую простые арифметические действия с двумя числами. Веб-службу можно рассматривать так же как и удалённую функцию, принимающую входные параметры и выдающую результат. Поэтому её функциональность можно описать следующим образом:
- a – первый аргумент;
- b – второй аргумент;
- op – арифметический оператор, выражаемый одним из знаков +, -, /, *.
- error – первый аргумент;
- result – второй аргумент;
Пример запроса/ответа — сумма
Пример запроса/ответа — разность
Пример запроса/ответа — произведение
Пример запроса/ответа — частное
Пример запроса/ответа – ошибка «деление на 0»
Пример запроса/ответа – ошибка «неверный формат числа»
Установка библиотек Jetty
Jetty очень удобен для создания веб приложений. Использование его как встроенного сервера освобождает разработчика от развёртывания веб приложения на внешний сервер при каждом запуске. Также это не требует установку внешнего сервера приложений.
Для большинства случаев достаточно загрузить библиотеки сервера, зарегистрировать их в Eclipse как библиотеку пользователя и далее использовать ссылку на эту библиотеку. Этот подход прост для начинающих Java программистов так как не требует наличия и навыков инструментария автоматизации сборки, такого как Maven или Gradle.
Установить необходимые библиотеки Jetty в Eclipse можно следующим образом:
1. Загрузим сжатый файл по ссылке http://download.eclipse.org/jetty/ и распакуем его;
2. В корневой папке проектов ( обычно это Workspace ) создадим папку jars, а в ней папку jetty;
3. Скопируем содержимое папки lib из распакованного ранее файла в созданную папку jetty;
4. В меню Window/Preferences выберем раздел Java/Build Path/User Libraries.
5. Кликнем кнопку New…, введём имя библиотеки jetty и кликнем кнопку ОК.
6. Далее при выделенной только что созданной библиотеке jetty в окошке Preferences кликнем кнопку Add External JARs…. В окне JAR Selection выберем все JAR-файлы из ранее созданной папки jars/jetty.
7. В итоге JAR-файлы будут загружены в пользовательскую библиотеку jetty. Хотя файлы, находящиеся в под-папках не будут загружены, для большинства случаев в них нет необходимости.
Создание проекта веб сервера
В меню File/New выберем Dynamic Web Project. В поле Project name введём SCalculator. Нажмём кнопку Finish.
Добавление ссылки на библиотеку jetty
Сразу после создания проект не содержит ссылку на библиотеку jetty. Подключённые библиотеки можно просмотреть в Project Explorer во вкладке Java Resources, в под-вкладке Libraries.
Кликнем правой кнопкой мыши на метку проекта и в контекстном меню выберем Build Path и далее Configure Build Path…. Во вкладке Java Build Path на страничке Libraries кликнем кнопку Add Library….
Выберем User Library и кликнем Next. Выберем jetty и кликнем Finish.
В итоге после подтверждения включения пользовательской библиотеки jetty, наличие ссылки на нее можно увидеть в Project Explorer.
Создание сервлета калькулятора
Создание файла сервлета
Сервлет калькулятора будет содержать весь код декодирования входных данных, вычисления, и формирования ответа. Для создания сервлета кликнем правой кнопкой мыши на наименование проекта в панели Project Explorer, в контекстном меню выберем New и далее Servlet. В название класса введём SrvltCalculator и кликнем кнопку Finish.
В панели Project Explorer можно увидеть созданный файл SrvltCalculator.java. Его содержимое автоматически открывается в редакторе.
Удаление лишнего кода
Для упрощения дальнейшего редактирования файлов удалим неиспользуемые конструктор сервлета SrvltCalculator и метод doPost.
Добавление импортируемых модулей
Код, который будет добавлен в файл сервлета потребует добавления следующих ниже строк кода включения модулей. Добавим эти строки.
Добавление кода в метод doGet
Метод doGet содержит код обработки GET–запросов. В этом методе последовательно добавим приведённые ниже фрагменты кода.
Приём параметров в соответствующие строковые переменные.
Объявление переменных для принятия декодированных из строковых переменных числовых параметров a и b.
Объявление переменной контроля возникновения ошибки noError.
Попытка декодирования числовых параметров a и b из соответствующих строковых переменных. При ошибке декодирования переменная noError принимает значение “ложь”.
Открытие секции кода для случая, если при декодировании числовых параметров ошибка не возникла.
Объявление числовой переменной result для хранения результата.
Открытие секции try для включения кода вычисления и контроля ошибок. Секция необходима, так как при арифметических операциях может возникнуть ошибка операции с плавающей запятой.
Для случая операции сложения, вызываем функцию functionSum, которую опишем позднее.
Для случая операции вычитания, вызываем функцию functionDif, которую опишем позднее.
Для случая операции умножения, вызываем функцию functionMul, которую опишем позднее.
Для случая операции деления, вызываем функцию functionDiv, которую опишем позднее. Так как для типа double ошибка деления на ноль на современных платформах не возникает, ситуацию в которой делитель равен нулю мы контролируем вручную.
После проверки всех четырёх операций устанавливаем флажок отсутствия ошибки в “ложь”. Это делается для идентификации того, что арифметическая операция не идентифицирована.
Закрываем блок try с установлением флажка отсутствия ошибки в “ложь” в случае возникновения исключительной ситуации.
В случае если ошибки не возникло, отсылаем результат методом doSetResult, который опишем ниже. Так как работа метода doGet на этом завершается, возвращаемся оператором return.
Закрываем секцию, начатую оператором “if ( noError ) <“:
Так как при обработке запроса где-то произошла ошибка и функция doGet не возвратила управление с успешным вычислением, возвращаем сообщение об ошибке методом doSetError, который опишем ниже.
Междоменные запросы
Междоменные запросы ( также такие запросы называются кроссдоменными / cross domain ) имеют место при запросах с веб страниц, расположенных вне сетевого домена обслуживающего сервера. Ответы на подобные запросы обычно блокируются для противостояния меж-доменным атакам. Для отключения блокировки в ответах сервера можно установить заголовок Access-Control-Allow-Origin:*.
Метод doSetResult
- Первая строка формирует JSON ответ. Так как структура ответа проста, специализированная библиотека JSON не используется;
- Во второй строке JSON ответ кодируется в тело HTTP ответа в двоичный вид посредством кодировки UTF-8;
- В третьей строке указывается тип содержания тела ответа HTTP;
- В четвёртой строке устанавливается разрешение на междоменные запросы;
- В пятой строке устанавливается флажок OK HTTP ответа.
Метод doSetError
- Первая строка формирует JSON ответ. Так как структура ответа проста, специализированная библиотека JSON не используется;
- Во второй строке JSON ответ кодируется в тело HTTP ответа в двоичный вид посредством кодировки UTF-8;
- В третьей строке указывается тип содержания тела ответа HTTP;
- В четвёртой строке устанавливается разрешение на междоменные запросы;
- В пятой строке устанавливается флажок OK HTTP ответа. Следует учесть, что сообщение содержит ошибку, связанную с арифметическими вычислениями. Так как эта ошибка не связана с протоколом HTTP, флажок статуса устанавливается в ОК.
Методы реализации арифметических операций
Архитектура рассматриваемого простого примера подразумевает разделение кода на функциональные части. Ввиду этого арифметические операции реализованы в виде отдельных функций, а не включены в тело метода doGet. Так как функции простые, их код комментировать не будем.
Исходный код программы можно найти в репозитории GitHub.
Создание основного класса
Основной класс приложения будет содержать функцию main – так называемую точку входа, с которой начинается работа программы. Функция main включит инициализацию, настройку и запуск встроенного сервера Jetty.
Для создания основного класса приложения кликнем правой кнопкой на наименовании проекта в панели Project Explorer, в контекстном меню выберем New и далее Class. В название класса введём Main. Установим флажок для создания статической функции main и кликнем кнопку Finish.
Так же как и в случае сервлета создаётся и открывается в текстовом редакторе соответствующий файл.
Добавление импортируемых модулей
Код, который будет добавлен в файл основного класса приложения потребует добавления следующих ниже строк кода включения модулей. Введём эти строки.
Добавление кода в метод main
Код метода main начинается с объявления переменной port и присваивания ей номера порта, который будет слушать сервер. Такой подход позволит быстро и легко изменить порт в случае необходимости в случае дальнейшего роста программы.
Создаем класс сервера.
Указываем параметры, которые свяжут путь строки запроса с созданным выше сервлетом.
Указываем серверу обработчик запросов.
Пробуем запустить сервер. Для того, чтобы работа программы не прекратилась, ждём завершения процесса сервера главным потоком посредством вызова server.join(). В случае возникновения ошибки печатается соответствующее сообщение.
Исходный код программы можно найти в репозитории GitHub.
Доступ к сервису из браузера
Запуск сервера
При запуске сервера Eclipse может предложить два варианта. Так как сервер содержит полноценный сервлет, то программа может быть запущена на сервере приложений, таком как к примеру Tomcat или самостоятельный Jetty. Однако так как мы встроили jetty в приложение, оно может работать самостоятельно – как Java Application.
После запуска приложение выдаёт соответствующие уведомления и строку Listening port: port, указывающую что наш сервер запущен и ждёт запросов.
Посылка запросов посредством браузера
Наиболее простой способ проверить функциональность сервера – обратиться к нему посредством браузера.
При посылке строки запроса, такой как http://localhost:8080/func?a=8.78&b=4.15&op=+ напрямую, сервер выдает ошибку. Дело в том, что строка не соответствует стандарту запросов и должна быть кодирована как URL ( символ + не допустим ).
После кодирования все работает без ошибки. Символ + кодирован URL как %2B, что делает запрос соответствующим стандарту. В интернете имеется множество он-лайн кодировщиков/де-кодировщиков URL, которыми можно воспользоваться для этой цели.
Аналогичным способом можно проверить ответы сервера на другие запросы.
Клиенты сервера
- специализированной веб страницы с автоматическим формированием строки запроса и форматированием ответа посредством JavaScipt;
- мобильным приложением;
- другим сервером, потребляющим созданный ресурс для своих внутренних нужд.
Клиент – веб страница
Специализированная веб страница – простой тип клиентского приложения.
HTML код страницы можно найти в репозитории GitHub.
Создание запускаемого модуля
Созданный сервер можно оформить как единый независимый запускаемый JAR-файл. Такой файл будет требовать только наличия установленной среды выполнения Java и запускаться из любой папки файловой системы. Для создания такого файла кликнем правой кнопкой мыши на наименовании проекта в панели Project Explorer, в контекстном меню выберем Export и далее Export…. В секции Java выберем Runnable JAR file и кликнем кнопку Next.
В настройках создаваемого JAR-файла указываем Launch configuration как Main-SCalculator, полное имя экспортируемого файла и флажок упаковки необходимых модулей в этот файл.
Запуск правильно созданного JAR-файла с именем SCalculator осуществляется простой командой (при запуске из той же папки, где он находится):
Также возможен запуск сервера двойным кликом мыши на JAR-файле.
Итоги
Многие описанные в этом выпуске элементы были практически использованы при создании высоконагруженных серверов. Несомненно были использованы и более продвинутые приёмы, позволившие достигнуть высокого быстродействия и надёжности, такие как использование сервера NGINX в режиме обратного прокси. Однако все начинается с простого и я надеюсь что смог просто и понятно описать приёмы, которые пригодятся при практической разработке.
Ссылки
Подробнее о встраивании Jetty в приложение можно почитать по ссылке http://docs.codehaus.org/display/JETTY/Embedding+Jetty
Представленный материал основан на использовании Eclipse Luna for Java EE Developers и Ubuntu 14.04.
Name already in use
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
Eclipse Jetty Canonical Repository
This is the canonical repository for the Jetty project, feel free to fork and contribute now!
Submitting a patch or pull request?
Make sure you have an Eclipse Contributor Agreement (ECA) on file.
Jetty is a lightweight highly scalable java based web server and servlet engine. Our goal is to support web protocols like HTTP, HTTP/2 and WebSocket in a high volume low latency way that provides maximum performance while retaining the ease of use and compatibility with years of servlet development. Jetty is a modern fully async web server that has a long history as a component oriented technology easily embedded into applications while still offering a solid traditional distribution for webapp deployment.