Primeira introdução ao protocolo HTTP, escrevendo o servidor Java Web mais simples

Eu acho que não seria exagero dizer que o conhecimento e a compreensão da essência do protocolo HTTP são necessários para quem decidiu levar a sério qualquer uma das áreas do desenvolvimento moderno da Web. Minha experiência pessoal sugere que o entendimento não vem imediatamente. Tenho vergonha de dizer que houve momentos em que as palavras GET e POST eram semelhantes a feitiços para mim, e eu nem suspeitava da existência de PUT, PATCH e DELETE.

Alguns meses atrás, além do próprio desenvolvimento, também comecei a ensinar, e surgiu a pergunta sobre como é mais fácil e mais claro contar aos futuros desenvolvedores Java sobre a essência do protocolo HTTP. Após vários dias de confusão e uma série de tentativas sem êxito de fazer uma apresentação, surgiu a idéia: por que não escrever o servidor HTTP mais simples em Java, porque não explica a essência do protocolo tão bem quanto sua implementação mais simples, mas funcional.

Como se viu, isso não é nada difícil. Abaixo está o código que será suficiente para a interação correta com qualquer navegador! Tudo o que precisamos é de um ServerSocket e algumas E / S padrão.

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.StandardCharsets; public class HttpServer { public static void main(String[] args) { try (ServerSocket serverSocket = new ServerSocket(8080)) { System.out.println("Server started!"); while (true) { //   Socket socket = serverSocket.accept(); System.out.println("Client connected!"); //      //    try (BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)); PrintWriter output = new PrintWriter(socket.getOutputStream())) { //     while (!input.ready()) ; //         System.out.println(); while (input.ready()) { System.out.println(input.readLine()); } //   output.println("HTTP/1.1 200 OK"); output.println("Content-Type: text/html; charset=utf-8"); output.println(); output.println("<p> !</p>"); output.flush(); //     try-with-resources , //         System.out.println("Client disconnected!"); } } } catch (IOException ex) { ex.printStackTrace(); } } } 

Tente executar este código. Note-se que a porta para a qual ServerSocket é criado deve estar livre. Se a porta especificada estiver ocupada, você deve liberá-la ou usar outra porta livre.

Após executar esse código, vá para a janela do navegador e digite a barra de endereço http://localhost:8080/ . Se tudo correu bem, na janela do navegador, veremos o texto "Olá pessoal" e no log do servidor, texto semelhante ao abaixo:

 Server started! Client connected! GET / HTTP/1.1 Host: localhost:8080 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,he;q=0.6,de;q=0.5,cs;q=0.4 Cookie: _ga=GA1.1.1849608036.1549463927; portainer.pagination_containers=100; _gid=GA1.1.80775985.1550669456; If-Modified-Since: Sat, 05 Jan 2019 12:10:16 GMT Client disconnected! 

Toda vez que inserimos algo na barra de endereços do navegador e pressionamos Enter, nada acontece além do envio de texto que começa com a palavra GET e termina com um feed de linha. Após a palavra GET, um espaço segue o caminho para o documento solicitado no servidor. Tente digitar http://localhost:8080/something no navegador e veja como o texto da solicitação no log é alterado.

Nas linhas de consulta, a partir do segundo estão os chamados cabeçalhos por meio dos quais as informações sobre as configurações do cliente são transmitidas ao servidor. Cada linha de cabeçalho possui o formato [ ] : []; []; ... [] [ ] : []; []; ... [] [ ] : []; []; ... [] .

Após a leitura completa do texto da solicitação pelo servidor, enviamos a ele a resposta mais simples, cuja estrutura é bastante simples e semelhante à estrutura da solicitação. A primeira linha contém a versão do protocolo HTTP e o código 200 OK , que informa ao navegador que a solicitação foi processada com êxito (todo mundo conhece melhor o código 404, não é?)). Isso é seguido por apenas um cabeçalho Content-Type no qual as informações sobre o formato do documento transmitido (texto / html) e sua codificação (charset = utf-8) são transmitidas. Após o cabeçalho, há um feed de linha (um requisito obrigatório do protocolo HTTP) e o texto real que será exibido no navegador.

Isso é tudo! Obviamente, isso está longe de tudo o que você precisa saber sobre o protocolo HTTP e os princípios do desenvolvimento de servidores da Web, mas eu não gostaria de complicar este exemplo, porque sua principal tarefa é demonstrar a comunicação mais simples através do protocolo HTTP. Em um dos meus próximos artigos, tentarei desenvolver o tópico de estudar o protocolo HTTP por meio de sua implementação.

UPD Um exemplo muito mais avançado desse servidor pode ser encontrado em Como o Tomcat funciona: um guia para desenvolver seu próprio contêiner de servlet Java de Paul Deck, Budi Kurniawan , capítulo 1 - Servidor Web simples .

UPD1. Seminário on-line com base neste artigo www.youtube.com/watch?v=RBUFdFKg_rI

Source: https://habr.com/ru/post/pt441150/


All Articles