segunda-feira, 5 de março de 2012

Dicas de Programação: Como fazer um serviço web em Java com socket?

Não, não vou implementar a especificação do J2EE em um "post" não (mesmo se eu tivesse tempo, acho que a explicação ficaria grande demais para isso...). :P

Mas você, implementador Java, já se perguntou como um servidor de páginas é feito?

Eu já, e por isso tentei implementar um pequeno "serviço" web em J2SE sem um servidor padrão (seja o Tomcat, o JBoss ou outro).

Vamos ao passos:

Primeiramente, eu pensei: preciso usar um ServerSocket para abrir conexão na rede na porta 8070 (por padrão, a porta do protocolo http é 80, mas preferi usar uma outra porta para evitar conflitos...).

public class Exemplo {
private ServerSocket server;

//Construtor da classe
public Exemplo() throws Exception {
       server = new ServerSocket(8070);
}
...
//"Destrutor da classe"
protected void finalize() {
      try {
           if (server != null) {
                server.close();
           }
     } catch (Exception e) {
           e.printStackTrace();
     }
}
}

Beleza! Depois disso, precisava que meu "servidor" sempre aceita-se a requisição de um cliente (por exemplo, um navegador) para esta porta e que minha aplicação "escreve-se" uma resposta para este... Como exemplo, fiz a resposta "padrão" para uma requisição do protocolo http de uma página web:

...
public void acceptAndResponse() throws Exception {
Socket client = server.accept();
String header = "HTTP/1.1 200 OK\n" +
        "Date: {0}\n" +
        "Server: Socket\n" +
        "Last-Modified: {0}\n" +
        "Accept-Ranges: bytes\n" +
        "Content-Length: {1}\n" +
        "Connection: close\n" +
        "Content-Type: text/html\n" +
        "\n"+
        "{2}";
Locale.setDefault(Locale.ENGLISH);
String now = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z").format(new Date());
String html = "\n" +
  "<html>\n"+
  "<head><title>Hello World!</title></head>\n" +
  "<body><h1>Hello World!</h1></body>\n" +
  "</html>\n";
String message = MessageFormat.format(header, now, String.valueOf(html.length()), html);
client.getOutputStream().write(message.getBytes());
client.close();
}
...

Mas, como eu teria que rodar isso continuamente, criei uma Thread para ficar eternamente executando a função acima...:

public class Exemplo implements Runnable {
...
public Exemplo() throws Exception {
       server = new ServerSocket(8070);
       Thread thread = new Thread(this);
       thread.start();

}
...
public void run() {   
       do {
            try {
                    this.acceptAndResponse();
            } catch (Exception e) {
                   e.printStackTrace();
            }
      } while (true);
}
...

E, no final, criei a função principal que chama tudo isso (está bem..., é o construtor que cria tudo, mas como era um teste, nem fiz questão de fazer um código "bonito"... :P ):
...
public static void main(String[] args) throws Exception {
       Exemplo e = new Exemplo();
}
...

Rodando a aplicação, eu fui ao navegador testar (endereço: http://localhost:8070) e, por incrivel que pareça, funcionou!

Legal, não?

Agora, quem reclamar da lentidão do Tomcat pode tentar fazer o seu servidor web. :)

Até mais!

Nenhum comentário: