Java – Criando um serviço WEB para executar fora de um container java (web server standalone with grizzly-http-server / jersey-server / javax.ws.rs)

javaeeNesta publicação vamos mostrar como criar um servidor web standalone, ou seja, vamos compilar o projeto como um jar e executa-lo pelo terminal sem a necessidade de precisar dar deploy em um container java (exemplo: glassfish, toncat, etc). Para isso vamos criar um projeto java com o maven para incluir as seguintes dependências:

javax: javaee-web-api
org.glassfish.grizzly: grizzly-http-server, grizzly-framework
org.glassfish.jersey.core: jersey-server, jersey-common, jersey-client
org.glassfish.jersey.media: jersey-media-sse, jersey-media-json-processing
org.glassfish.jersey.containers: jersey-container-grizzly2-http, jersey-container-servlet

Essas dependências permitem criar um web server e subir sua aplicação em um container próprio. As dependências do javax nos permite criar o serviço web REST, a grizzly fica responsável pelo servidor web e a jersy pelo container. Nesse projeto não vamos chegar a usar todas essas dependências porem vamos deixar no projeto.

Iniciaremos o projeto configurando o pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <name>WebServerStandalone</name>
    
    <modelVersion>4.0.0</modelVersion>
    <groupId>br.com.helpdev</groupId>
    <artifactId>WebServerStandalone</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <!-- packaging: jar ou war -->
    <packaging>jar</packaging>

    <properties>
        <!-- endorsed.dir: utilizado para projetos WEB/Glassfish -->
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- Versões utilizadas para as dependencias jersey e grizzly para rodar o server standalone -->
        <version.jersey>2.25.1</version.jersey>
        <version.grizzly>2.3.31</version.grizzly>
        <!--Versão java source e target-->
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <!-- java.mainClass: Java main Class -->
        <java.mainClass>br.com.helpdev.webserver.Main</java.mainClass>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        
        <!-- ABAIXO DEPENDENCIAS PARA SERVIDOR STANDALONE: -->
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>${version.jersey}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-common</artifactId>
            <version>${version.jersey}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>${version.jersey}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-sse</artifactId>
            <version>${version.jersey}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-grizzly2-http</artifactId>
            <version>${version.jersey}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>${version.jersey}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-processing</artifactId>
            <version>${version.jersey}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.grizzly</groupId>
            <artifactId>grizzly-http-server</artifactId>
            <version>${version.grizzly}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.grizzly</groupId>
            <artifactId>grizzly-framework</artifactId>
            <version>${version.grizzly}</version>
        </dependency>
        <!-- ACIMA DEPENDENCIAS PARA SERVIDOR STANDALONE -->
        
    </dependencies>

    <build>
        <plugins>
            <!-- FAT-JAR -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.4.1</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>libs/</classpathPrefix>
                            <mainClass>${java.mainClass}</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            
            <!-- JAR EXTERNAL LIBS -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>libs/</classpathPrefix>
                            <mainClass>${java.mainClass}</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.4</version>
                <executions>
                    <execution>
                        <id>copy</id>
                        <phase>install</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>
                                ${project.build.directory}/libs
                            </outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            
            <!-- ABAIXO PLUGINS PARA GERAR WAR -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>7.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

O arquivo pom.xml acima está bem completo, com ele podemos até gerar um war caso posteriormente fosse necessário subir sua aplicação em um container como o glassfish. Basta apenas trocar a tag “packaging” com o valor de jar para war.

Com todas as dependências configuradas vamos iniciar um servidor e já criar nossa Main.java:

/**
 *
 * @author helpdev.com.br
 */
public class Main {

    //Endereço para rodar o serviço:
    public static final URI SERVER_URL
            = URI.create("http://127.0.0.1:8080/myserver");

    public static void main(String[] args) throws IOException {
        //Iniciando o servidor
        Main main = new Main();
        HttpServer server = main.newServer();
        server.start();
        //Aguardando qualquer entrada no terminal para finalizar o servidor:
        System.in.read();
        server.shutdownNow();
    }

    public HttpServer newServer() {
        //Configura o package dos serviços WEB
        ResourceConfig resourceConfig = new ResourceConfig()
                .packages("br.com.helpdev.webserver.rest");
        //Cria o serviço HTTP
        HttpServer server = GrizzlyHttpServerFactory
                .createHttpServer(SERVER_URL, resourceConfig);
        return server;
    }
}

Pronto. Temos um servidor http rodando e escutando em “http://127.0.0.1:8080/myserver” (localhost). Deixamos configurado o package “br.com.helpdev.webserver.rest” para inserir nossos serviços. Agora vamos criar um serviço REST simples para testarmos:

package br.com.helpdev.webserver.rest;
[...]
/**
 *
 * @author helpdev.com.br
 */
@Path("teste")
public class WebRestTest {

    @Context
    private UriInfo context;
    @Context
    private HttpHeaders headers;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getXml() {
        return "</xml>";
    }

    @POST
    @Path("{codOp}")
    @Consumes(MediaType.TEXT_PLAIN)
    public Response postXml(@PathParam("codOp") int codOp, String content) throws Exception {
        return Response.ok().build();
    }
}

A classe WebRestTest é um serviço REST simples com um GET e um POST o serviço está rodando no path /teste, o get vai nos retornar um texto qualquer e no post em /teste/{codOp} vamos passar um conteudo do tipo text.

Para testarmos nossa aplicação basta rodar o Main.java e executar a classe de teste:

/**
 * Classe para testar o web server standalone
 *
 * @author helpdev.com.br
 */
public class ClientTest implements AutoCloseable {

    private final WebTarget webTarget;
    private final Client client;
    private static final String BASE_URI = "http://127.0.0.1:8080/myserver";

    public static void main(String[] args) {
        try (ClientTest clientTest = new ClientTest()) {
            System.out.println("getXml: {" + clientTest.getXml() + "}");
            System.out.println("postXml: {" + clientTest.postXml("abc", "1") + "}");
        }
    }

    public ClientTest() {
        client = javax.ws.rs.client.ClientBuilder.newClient();
        webTarget = client.target(BASE_URI).path("teste");
    }

    public String getXml() throws ClientErrorException {
        WebTarget resource = webTarget;
        return resource.request(javax.ws.rs.core.MediaType.TEXT_PLAIN).get(String.class);
    }

    public Response postXml(Object requestEntity, String codOp) throws ClientErrorException {
        return webTarget.path(java.text.MessageFormat.format("{0}", new Object[]{codOp})).request(javax.ws.rs.core.MediaType.TEXT_PLAIN).post(javax.ws.rs.client.Entity.entity(requestEntity, javax.ws.rs.core.MediaType.TEXT_PLAIN), Response.class);
    }

    public void close() {
        client.close();
    }

Para mais informações o projeto se encontra no nosso GITHUB: https://github.com/helpdeveloper/JavaSample-WebServerStandalone

Help DEV – Analista desenvolvedor Java / Android

http://helpdev.com.br/zarelli

Deixe uma resposta

O seu endereço de email não será publicado Campos obrigatórios são marcados *

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>