Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
April 20, 2023 01:26 am GMT

Como criar um Servidor Web Java Sem Framework

Ol, espero que voc esteja bem Uma das coisas que gosto de fazer ao iniciar meus estudos em uma tecnologia, entender como as coisas funcionam nos nveis mais bsico da ferramenta, ou seja, construir algo sem o auxlio de frameworks. Assim, passo a ter uma boa noo do que framework e o que a nativo da ferramente.

A proposta aqui criar e configurar o projeto de um servidor backend simples na linguagem Java, que execute no ambiente local e possua uma rota get que imprima uma mensagem de Hello, World! padro. Ademais, a ideia codificar o servidor tentando utilizar o nvel mais bsico e nativo e entender o que cada ferramenta ou configurao altera no projeto.

Quais so os pr-requisitos?

Para iniciar, como quero o menor auxlio possvel de outras ferramentas, no vou escolher uma IDE JAVA, uma vez que esse software me ajudaria nessa parte de configurao inicial, no me deixando livre para percorrer o caminho das pedras que meu propsito. Por isso, o editor de texto que estarei usando o Visual Studio Code.

A escolha do VS-code no influenciada por ser o editor que mais gosto mas sim por eu precisar de uma ferramenta que me auxilie o mnimo, mas que ainda torne esse processo operacional. Diferente de utilizar um bloco de notas, que no mostra em destaque as palavras chave ou no Vi ou Nano que so editores que rodam no terminal, que eu particularmente tenho dificuldade de navegar entre o cdigo.

Alm do editor de texto, preciso claro, do JDK. A sigla para Java Development Kit, compreende o conjunto de ferramentas que os desenvolvedores usam para criar aplicativos em Java. Dentro dele esto inclusos o compilador, depuradores, documentadores e outras ferramentas.

Para saber se voc possui o JDK instalado em sua mquina, no terminal execute o comando

java -versionjavac -version

Como sada, voc deve ver algo parecido com isso, variando a verso do Java que voc instalou. Para este projeto estou usando a verso **11.0.7** do Java.

Image description

Se voc no tiver o JDK instalado, voc pode baix-lo e instal-lo a partir do site oficial da Oracle ou do OpenJDK.

Familiarizando-se com o Java

Com tudo configurado, vou fazer um pequeno teste criando um arquivo que imprime Hello, World!, compilar e executar atravs do terminal.

No diretrio do projeto, vou criar a pasta **src** onde ficar os arquivos fontes do projeto, e dentro dela, o arquivo **Main.java**. Perceba que a extenso do arquivo **.java**, isso indica que se trata de um arquivo fonte, ou seja, o arquivo onde o programador escrever o cdigo propriamente dito. Dentro desse arquivo estarei criando a classe que leva o mesmo nome, e o mtodo **main**.

public class Main {  public static void main(String[] args) {        String greeting = "Hello, World!";    System.out.println(greeting);  }}

O mtodo public static void main(String[] args)
em Java o ponto de entrada para qualquer programa em Java. o mtodo que executado primeiro quando voc executa um programa Java a partir da linha de comando ou do IDE. Em programao, funes main semelhantes essa so chamadas de *********Entry point.*********

Com o cdigo criado, o prximo passo a compilao. Para isso, atravs de um terminal, navegue at a pasta do projeto e execute o seguinte comando:

javac src/Main.java

Se no apareceu nenhuma sada no terminal, no diretrio src se encontra o bytecode do nosso programa em Java. Bytecode uma forma de representar um programa Java compilado em uma linguagem intermediria que interpretada pela Java Virtual Machine (JVM).

Agora, para executar nosso programa utilizamos o comando:

java -cp src Main

O parmetro -cp especifica o classpath, ou seja, o caminho onde a JVM deve procurar pelas classes referenciadas pelo programa. Neste caso, estamos especificando que a pasta "src" contm as classes do programa.

Hora do show

Com tudo pronto, testado e funcionando, podemos avanar para a parte que de criao do nosso servidor propriamente dito. Para isso teremos que fazer a importao de 3 mdulos do Java.

import com.sun.net.httpserver.HttpServer;import java.io.IOException;import java.net.InetSocketAddress;public class Main {  public static void main(String[] args) {        String greeting = "Hello, World!";    System.out.println(greeting);  }}

A razo pela qual voc precisa fazer o import desses mdulos que eles no esto includos na biblioteca padro do Java. A classe com.sun.net.httpserver.HttpServer pertence API do servidor HTTP incorporado, que uma parte do JDK, mas no includa por padro em todos os ambientes de execuo do Java. Da mesma forma, as classes java.io.IOException e java.net.InetSocketAddress so parte da biblioteca padro do Java, mas precisam ser importadas porque so usadas no cdigo e no esto no pacote padro.

Alm disso, mesmo que as classes estejam no pacote padro, uma boa prtica import-las explicitamente para deixar o cdigo mais claro e fcil de entender.

  1. com.sun.net.httpserver.HttpServer

Esse o mdulo da API do servidor HTTP incorporado que fornecido pelo JDK. Essa API permite que voc crie um servidor web em Java sem precisar usar uma biblioteca de terceiros ou um servidor web externo. A classe HttpServer representa o servidor web em si, e responsvel por gerenciar as conexes de entrada e sada, bem como pelo roteamento das solicitaes para as classes de manipuladores correspondentes.

  1. java.io.IOException

Este import necessrio para que o servidor HTTP incorporado possa lanar uma exceo de IOException. Isso acontece porque o servidor precisa criar um (socket) para escutar as conexes de entrada. No entanto, pode haver problemas ao criar o soquete, como falha na conexo, porta em uso ou outro erro. A exceo IOException lanada quando ocorre um erro na criao do soquete. Essa exceo uma exceo verificada, o que significa que o cdigo precisa lidar com ela de alguma forma (como mostrado na resposta anterior).

  1. java.net.InetSocketAddress

Este import necessrio porque a classe HttpServer precisa de um objeto InetSocketAddress para determinar qual porta e endereo IP usar para escutar as conexes de entrada. por isso que a criao de um objeto InetSocketAddress um passo importante na criao de um servidor HTTP incorporado, porque ele especifica onde o servidor web estar "ouvindo" as solicitaes HTTP recebidas.

Repare que at aqui, apenas fizemos os imports necessrios para os mdulos bsicos, disponveis no JDK, para a criao do nosso servidor web.

Como j comentado, o mdulo de **IOException** importante para lanar uma exceo. No Java, uma Exception uma classe que representa uma condio excepcional que ocorre durante a execuo de um programa. Ao ocorrer um erro, uma instncia de uma classe de Exception criada e lanada, interrompendo a execuo normal do programa. As Exceptions permitem que os programas lidem com erros e situaes excepcionais de forma mais controlada.

Por isso, faremos uma pequena alterao no cdigo fonte do servidor utilizando a palavra **throws** aps a assinatura do nosso entry point. O throws uma declarao que informa que um mtodo pode lanar uma exceo durante a sua execuo.

import com.sun.net.httpserver.HttpServer;import java.io.IOException;import java.net.InetSocketAddress;public class Main {  public static void main(String[] args) throws IOException {        String greeting = "Hello, World!";    System.out.println(greeting);  }}

Como prximo passo, devemos criar uma instncia que representa o endereo e a porta em que o servidor deve ser executado. Para isso utilizaremos a classe InetSocketAddress. A classe InetSocketAddress possui dois construtores que podem ser utilizados para instanciar um objeto. O primeiro deles recebe um objeto do tipo InetAddress e um nmero de porta, e o segundo recebe uma string com o endereo IP ou nome do host e um nmero de porta.

Aqui est uma explicao mais detalhada de cada um dos parmetros:

  • InetAddress: um objeto que representa um endereo IP. Ele pode ser obtido atravs da classe InetAddress do Java. Ao utilizar esse parmetro, estamos especificando o endereo IP do servidor ou cliente que ser utilizado na conexo.
  • String: uma string que representa o endereo IP ou nome do host. Ele til quando queremos criar uma instncia de InetSocketAddress a partir de uma string. Por exemplo, se quisermos criar um endereo a partir de uma string "localhost", podemos passar essa string como parmetro.
  • int: um nmero inteiro que representa a porta que ser utilizada na conexo. A porta utilizada para especificar o canal de comunicao que ser utilizado pelo servidor ou cliente.

Ao instanciar um objeto de InetSocketAddress, precisamos passar esses parmetros no construtor de acordo com o que desejamos.

Para deixar mais didtico, declarei uma varivel do tipo **String** com o identificador **host** e uma varivel do tipo int com o identificador **port**, alm de alterar nossa antiga varivel chamada **greetings** para **response**.

import com.sun.net.httpserver.HttpServer;import java.io.IOException;import java.net.InetSocketAddress;public class Main {  public static void main(String[] args) throws IOException {    int port = 8080;    String host = "localhost";    String response = "Hello, World!";    InetSocketAddress address = new InetSocketAddress(host, port)        System.out.println(response);    }}

Por fim a cereja do nosso bolo, a classe responsvel por criar o servidor HTTP. A classe HttpServer, que pode ser usada para criar um servidor HTTP que ouve em uma porta especfica e manipula solicitaes HTTP de entrada,

A classe HttpServer fornece um mtodo esttico create() que cria uma instncia do servidor HTTP. O mtodo create() aceita dois parmetros: um InetSocketAddress e um int que indica o nmero mximo de solicitaes que o servidor pode manipular simultaneamente. Quando o servidor recebe uma solicitao, ele cria uma nova thread para manipular a solicitao e liberar o thread principal para lidar com novas solicitaes.

import com.sun.net.httpserver.HttpServer;import java.io.IOException;import java.net.InetSocketAddress;public class Main {  public static void main(String[] args) throws IOException {    int port = 8080;    String host = "localhost";    String response = "Hello, World!";    InetSocketAddress address = new InetSocketAddress(host, port)        HttpServer server = HttpServer.create(address, 0);        System.out.println(response);    }}

Agora precisamos criar um contexto para o servidor HTTP, indicando o que deve acontecer quando o servidor receber uma requisio para a rota "/" (root). No contexto de um servidor HTTP, o termo "contexto" se refere a um mapeamento entre uma determinada URL e uma funo ou mtodo que deve ser executado para lidar com as requisies feitas para essa URL.

import com.sun.net.httpserver.HttpServer;import java.io.IOException;import java.net.InetSocketAddress;public class Main {  public static void main(String[] args) throws IOException {    int port = 8080;    String host = "localhost";    String response = "Hello, World!";    InetSocketAddress address = new InetSocketAddress(host, port)        HttpServer server = HttpServer.create(address, 0);        server.createContext("/", (exchange -> {}));        System.out.println(response);    }}

server.createContext("/", (exchange -> {...} cria um contexto para a URL raiz ("/") e define uma funo lambda para lidar com as requisies feitas para essa URL. O conceito de lambda no Java uma expresso que representa uma funo annima, que pode ser passada como argumento para um mtodo ou atribuda a uma varivel.

A palavra-chave exchange representa a troca de informaes entre o cliente e o servidor. A funo lambda recebe esse objeto exchange como parmetro e, a partir dele, possvel acessar e manipular os dados da requisio e da resposta.

Com o contexto criado precisamos aplicar algumas configuraes para definir o formato do contedo da resposta.

import com.sun.net.httpserver.HttpServer;import java.io.IOException;import java.net.InetSocketAddress;public class Main {  public static void main(String[] args) throws IOException {    int port = 8080;    String host = "localhost";    String response = "Hello, World!";    InetSocketAddress address = new InetSocketAddress(host, port)        HttpServer server = HttpServer.create(address, 0);        server.createContext("/", (exchange -> {            exchange.getResponseHeaders().set("Content-Type", "text/plain");            exchange.sendResponseHeaders(200, response.getBytes().length);      exchange.getResponseBody().write(response.getBytes());      exchange.close();        }));        System.out.println(response);    }}

Dentro da funo lambda, primeiro definido o tipo do contedo da resposta, usando o mtodo set() do objeto getResponseHeaders().

Em seguida, o cdigo envia a resposta ao cliente, indicando o cdigo de status 200 (OK), o tamanho da resposta e o contedo em si, usando os mtodos sendResponseHeaders(), getResponseBody() e write() do objeto exchange.

Por fim, o mtodo close() chamado para encerrar a troca de informaes entre o cliente e o servidor.

Ao final, precisamos inicializar nosso servidor web. O mtodo server.start() responsvel por iniciar o servidor HTTP. Aps a chamada desse mtodo, o servidor comea a ouvir as solicitaes HTTP recebidas na porta e host especificados.

A ltima linha, System.out.println("Servidor iniciado em http://localhost:8080/");, exibe uma mensagem no console informando ao usurio que o servidor foi iniciado com sucesso e em qual URL ele est sendo executado. Essa mensagem apenas informativa e no interfere no funcionamento do servidor. uma forma de indicar ao usurio que o servidor est pronto para receber as solicitaes.

import com.sun.net.httpserver.HttpServer;import java.io.IOException;import java.net.InetSocketAddress;public class Main {  public static void main(String[] args) throws IOException {    int port = 8080;    String host = "localhost";    String response = "Hello, World!";    InetSocketAddress address = new InetSocketAddress(host, port)        HttpServer server = HttpServer.create(address, 0);        server.createContext("/", (exchange -> {            exchange.getResponseHeaders().set("Content-Type", "text/plain");            exchange.sendResponseHeaders(200, response.getBytes().length);      exchange.getResponseBody().write(response.getBytes());      exchange.close();        }));        server.start();    System.out.println("Servidor iniciado em http://" + host + ":" + port + "/");    }}

Consideraes finais

Em resumo, esse projeto cria um servidor HTTP simples na porta 8080 e no host "localhost". Quando uma solicitao HTTP get feita para a URL raiz "/", o servidor responde com o texto "Hello

World!".

O mtodo main() responsvel por inicializar o servidor e definir o contexto para a URL raiz "/". Dentro do contexto, definida uma funo lambda que trata a solicitao HTTP recebida. Nessa funo, definido o tipo de contedo da resposta como "text/plain", o cdigo de status da resposta como 200 (OK), o corpo da resposta como o texto "Hello World!" e, por fim, a resposta enviada para o cliente e a conexo fechada.

Por fim, o servidor iniciado e uma mensagem exibida no console informando a URL em que o servidor est sendo executado.

Neste artigo, vimos como criar um servidor web Java simples sem o uso de nenhum framework. Com apenas algumas linhas de cdigo, possvel criar um servidor que recebe solicitaes HTTP e responde com o contedo desejado.

Embora seja possvel criar um servidor web Java sem framework, importante lembrar que frameworks como Spring e Spark oferecem muitas funcionalidades teis que podem acelerar o desenvolvimento de um aplicativo web.

Se voc quiser ver o cdigo completo do servidor web Java que criamos neste artigo, confira o meu projeto no GitHub: pure-java-server.

Espero que este artigo tenha sido til e que voc tenha aprendido algo novo sobre como criar um servidor web Java simples. Fique vontade para compartilhar suas ideias e comentrios abaixo. At a prxima!


Original Link: https://dev.to/diogoizele/como-criar-um-servidor-web-java-sem-framework-21d6

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To