Comments 42
Вот совсем не так устроен, даже не близко.
Для начала сделайте обработку запроса в отдельном треде: либо новом, либо из пула. Это добавит всего пару строк, но сделает ваш сервер многопользовательским. А то вы так бодро и оптимистично из сокета читаете, что как-будто кто-то обязан доставить вам незамедлительно весь http-запрос, а также моментально отправить ваш ответ. А вот треды исключат блокировку, и ваш сервер сразу станет актуальным на период до 2002 года.
В 2002 году вышла Java 1.4, в которой, наконец, запилили неблокирующий NIO, который предлагал совершенно другую модель взаимодействия. Треды стали ненужны, ну или не столь актуальны, но прогать стало на порядки сложнее. Поэтому Apache Mina или Netty.
Поверьте, я про это знаю) Но в данном случае такой задачи даже близко не стояло. Задача была написать короткий и простой код, которого достаточно чтобы принять HTTP запрос и ответить на него так, чтобы браузер понял. Это материал для совсем новичков, кто раньше никогда не писал веб приложений.
Но видимо текст не очень хорошо написан, если приходится в который раз это объяснять. Увы.
Если хотите показать, как работают сокеты, что сделайте чат на сокетах.
Если хотите рассказать про HTTP, то нужно рассказывать про стандарты и реализации, иначе вы сделаете для студентов только хуже, упростив пример ниже допустимого минимума.
что за всем этим стоит не более чем пересылка текстовых сообщений определенного содержания
Ну это же неверно.
Вся суть HTTP — именно в спецификациях. Посмотрите, например, как лишь малую часть спецификации обсуждают в этой этой недавней теме REST страсти по 200.
Это опасно, чрезмерно упрощать тему и ставить акценты совершенно на другой уровень. Это сильно вводит в заблуждение.
Если хотите показать работу с сокетами, то сделайте простой чат.
Если ходите рассказать сетевую модель, то покажите это: ru.wikipedia.org/wiki/Сетевая_модель_OSI
И работы сокетов там на несколько строк. Все остальное это огромная обертка, которую я никак не могу заставить себя продолжить писать.
Пример выше как раз отлично показывает работу сокетов «на один экран».
Пример выше как раз отлично показывает работу сокетов «на один экран».
Если хочется показать работу сокетов на примере HTTP, то нужно делать «простейший HTTP/1.0-клиент», а не сервер.
А преподавать что-то не зная сути вопроса я бы вообще не рискнул. Больше будет вреда, чем пользы.
Ну, тут то как раз логика понятна. Напишем крошечный сервер, а потом такой же клиент для него. Чтобы так сказать «полное покрытие было».
На самом деле, можно продемонстрировать работу клиента и «авторитетной вещи», например, обратившись к «google.com» по порту 80.
Или на «ya.ru» с запросом:
GET / HTTP/1.1
Host: ya.ru
И, включив отладку в браузере (Ctrl+Shift+I) и показав, что тоже самое видит и браузер.
И для этого совсем не обязательно даже писать программу, достаточно использовать telnet.
А упор при рассказе про HTTP нужно делать на понятия, стандарты, сценарии, демонстрации с помощью браузерного инструмента разработчика: developers.google.com/web/tools/chrome-devtools/network
HTTP перестанет быть «абстрактным конем в вакууме».
По моему мнению, это введение в заблуждение.
Если вы сделаете «Простой HTTP/1.0-клиент», то претензий к вам, по сути, не будет.
Если вы заявляете, что сделали «Простой HTTP-сервер», то это опасное введение в заблуждение.
Собственно, в этом и была цель! А если сравнивать с чатом, то тут в качестве клиента выступает не какой-то ещё кусок кода, а такая всем хорошо известная вещь, как веб браузер.
habr.com/ru/post/69136
По-моему вполне полезная статья. А если написать вторую часть, с примерами разбора и парсинга/фильтрации параметров, так совсем хорошо будет. Хоть джуны, которые кроме спринг-бута ничего больше и не видели, смогут посмотреть "как это сделано"
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class App {
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
server.createContext("/test", new MyHandler());
//Thread control is given to executor service.
server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());
server.start();
}
static class MyHandler implements HttpHandler {
@Override
public void handle(HttpExchange t) throws IOException {
String response = "This is the response";
long threadId = Thread.currentThread().getId();
System.out.println("I am thread " + threadId );
response = response + "Thread Id = "+threadId;
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
}
Продолжайте! На самом деле этой темы на 5 небольших статей легко хватит.
Мне понятно, что можно и не писать очередную статью, а отправить "гуглить" или смотреть исходники популярных библиотек…
Но тем и хорош хабр, что дает возможность на базе таких статей обсудить те или иные решения.
Например так старался делать Иван Головач в своих статьях: ivangolovach
Стоит взять в привычку никогда не испольовать Reader/Writer обертки без явного указания кодировки:
// не надо так
new InputStreamReader(socket.getInputStream())
// надо так
new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)
Такой подход спасет от большого количества боли.
Первое знакомство с протоколом HTTP через написание простейшего Web сервера на Java