1
resposta

Criei meu proprio sistema para HTTP Server usando Java puro

JToolbox HTTP Service: Um Roteador Leve em Java

Criei um sistema de HTTP Service completo em Java puro (Vanilla Java), com foco em simplicidade e agilidade, semelhante a frameworks leves como o Gin Gonic em Go. A proposta principal é permitir que você crie rapidamente mini-projetos ou mock servers para realizar testes de integração, validando suas requisições HTTP (GET, POST, PUT, DELETE, etc.) de forma eficiente.

A Criação de Endpoints e Handlers

O núcleo deste serviço reside na definição de endpoints e na associação de Handlers. Um endpoint é a combinação única de um método HTTP e um caminho (path).

Para começar, você precisa apenas chamar a classe Server, definir a porta de execução e encadear os métodos HTTP (como get, post, delete) para criar seus endpoints.

O Fluxo de Roteamento

  1. Inicialização: Chame Server.port() para iniciar o serviço na porta desejada (ex: 8080).
  2. Definição do Endpoint: Use métodos como .get("/caminho") para mapear a URL.
  3. Associação do Handler: O segundo argumento é a função lambda ou a classe que implementa a interface Handler — o código que será executado para processar a requisição e construir a resposta.

O Contexto da Requisição (HttpContext)

O HttpContext é o objeto central passado para cada Handler, contendo todos os utilitários para interagir com a requisição e montar a resposta. Com ele, você pode:

  • Acessar query parameters (ex: ctx.param("id")).
  • Ler o corpo da requisição (ctx.body()) e desserializá-lo para classes Java.
  • Definir headers de resposta (ex: ctx.header("Content-Type", "text/html")).
  • Enviar a resposta final com diferentes tipos (JSON, texto) e códigos de status (ctx.send(), ctx.json(), ctx.text()).

Exemplo 1: Servindo um Conteúdo Estático na Raiz

Este exemplo demonstra como servir o conteúdo de um arquivo HTML estático na rota raiz (/), garantindo que falhas na leitura do arquivo sejam tratadas com um erro 500 (Internal Server Error).

public class WebServer {
    public static void main(String[] args) {

        Server server = Server.port(8080)
                .get("/", ctx -> {
                    String content = Try.ofThrowing(() ->
                                            File.read("./static/index.html")
                            )
                            .onFailure(e -> {
                                Logger.error("Error reading index.html: {}", e, e.getMessage());
                                ctx.status(500, HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase());
                                ctx.text("Error: Could not read index.html file.");
                            })
                            .orElse(null);
                    if (content != null) {
                        ctx.header("Content-Type", "text/html");

                        ctx.send(HttpStatus.OK, content);
                    }
                });
        server.start();
    }
}

Exemplo 2: Criando Handlers Reutilizáveis (Classes)

Para encapsular lógica de negócios mais complexa ou para promover a reutilização, você pode criar uma classe que implementa a interface Handler:

class Hello implements Handler {

    @Override
    public void handle(HttpContext ctx) {
        ctx.header("Content-Type", "text/html");
        ctx.send(HttpStatus.OK, "Hello World!");
    }
}

Exemplo 3: Handlers como Métodos Estáticos e não Estáticos (Lambdas)

Para endpoints simples e concisos, a criação de métodos publicos e/ou estáticos que retornam a interface Handler usando lambdas é a abordagem mais elegante e funcional:

public Handler hello() {
        return ctx -> ctx.send(HttpStatus.OK, "Hello World!");
}

Como ficou o web site estático:
webserver

Esta minha lib esta disponivel no repositorio da Maven Central

Matricule-se agora e aproveite até 50% OFF

O maior desconto do ano para você evoluir com a maior escola de tecnologia

QUERO APROVEITAR
1 resposta

Oi, Rick! Como vai?

Com base no que você explicou, gostei de como você organizou os handlers e trouxe uma arquitetura leve para criação de rotas usando Java puro. O jeito como você usou lambdas e classes reutilizáveis mostra um domínio interessante do fluxo HTTP e uma boa separação de responsabilidades.

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!