Технологии программирования
Веб-сервер на java
Предисловие 1. Немного про TCP-IP
Как же нам из приложения отправить запрос на сервер, использую эти ваши интернеты?
На примере доставки подарочной плитки шоколадки:
- Мы сначала нашу подарочку плитку должны упаковать
- Потом на уровне доставочной службы перевести к вашему другу
- А потом на уровне друга - распаковать и получить исходную шоколадку
Какие же есть протоколы? Об этом вам подробнее расскажут на Вычислительных системах и компьютерных сетях. Если вкратце - есть различные протоколы, которые определяют различные действия на различных этапов передачи данных между программами.
Так сложилось, что есть две модели, описывающие уровни протоколов. Одна из них теоретическая – модель OSI, а другая практическая – TCP/IP.
- message - генерируется на уровне приложения (может быть http запрос)
- TCP или UDP header - присоединяется на транспортном уровне (информация о портах и другая)
- IP - заголовок - межсетевой уровень (адреса компьютеров)
- by the way - message + TCP header + IP header = пакет данных
- Ethernet header + Ethernet footer - канальный уровень
Таким образом работа протоколов на пути нашего сообщения идет следующим образом:
Предисловие 2. Немного про HTTP и REST API
Протокол HTTP:
- Протокол прикладного уровня, верхнего в моделях OSI и TCP-IP
- Основа - клиент-серверная архитектура программ. Клиент формирует запрос, сервер на него формирует ответ.
- Манипулирует над ресурсом, на который указывает URI (URL и URN - частные случаи URI)
Запрос HTTP
Запрос HTTP состоит из следующих элементов:
Ответ HTTP
Методы HTTP
- get (нет тела запроса)
- post (идемпотентны)
- put
- delete
Коды ответов
Пример запроса
Java Servlets
Веб-контейнер - программа. В веб-контейнере развернут набор сервлетов.
После того как соединение установлено, веб-контейнер формирует 2 объекта: HttpServletReuest and HttpServletResponse.
Зависимости gradle:
compileOnly 'jakarta.servlet:jakarta.servlet-api:5.0.0'
Пример сервлета:
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/ping")
public class PingServlet extends HttpServlet {
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String reply = "<h1>pong</h1>";
response.getOutputStream().write( reply.getBytes("UTF-8") );
response.setContentType("text/html; charset=UTF-8");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setStatus( HttpServletResponse.SC_OK );
// if response will have body
// response.getOutputStream().write( reply.getBytes("UTF-8") );
}
}
Также можем заимплементить doPost, doPut, doDelete
Экземпляры сервлета создает веб-контейнер в рантайме. После этого сервлет в рантайме может обрабатывать запросы. Веб-контейнер плодит по отдельному потоку на каждый запрос, приходящий к нему, и сервлеты соответственно эти запросы обрабатывают.
Jetty Server
Теперь нам нужен контейнер для наших сервлетов. Наиболее распространенные веб-сервера на java - Tom Cat, Jetty и др. На этой лекции для избежания взрыва мозга посмотрим на Jetty, тк он кажется чуть проще.
Jetty — свободный контейнер сервлетов, написанный полностью на Java.
Конечно нам потребуются зависимости в gradle:
implementation 'org.eclipse.jetty:jetty-servlet:11.0.14'
implementation 'org.eclipse.jetty:jetty-server:11.0.14'
Создадим стартовый класс для нашего сервера:
public class JettyServer {
private Server server;
public void start() throws Exception {
int port = 8080;
Server server = new Server(8080);
ServletContextHandler handler = new ServletContextHandler(server, "/");
handler.addServlet(PingServlet.class, "/ping");
try {
server.start();
System.out.println("Listening port : " + port );
} catch (Exception e) {
System.out.println("Error.");
e.printStackTrace();
}
}
}
REST API
host/insert-student - неверно host/put-all-5-marks
url host/student/5/marks?new-mark=5 method post
get host/student
Полезные ссылки
Очень классная статья про TCP и UDP