Blog

Criando e consumindo WebServices REST em Java


Assim como explicado no artigo "Criando e consumindo WebServices SOAP em Java" é muito comum que cada vez mais analistas optem por utilizar uma arquitetura distribuída e busquem tornar seus projetos prontos para operarem em multiplataformas. Evidentemente, existem muitas práticas necessárias para atingir este objetivo e, portanto, não se trata apenas de uma prática ou outra, mas sim o conjunto delas. Neste artigo apenas será abordado uma das tecnologias disponíveis para isso.

Para tornar mais fácil a compreensão da tecnologia, foi utilizado um exemplo de uma consulta de endereço por CEP com apenas um método com um retorno fixo simples. 


package com.joaofelipe.cep;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Endereco {

    public String estado;
    public String cidade;
    public String bairro;
}


Nota-se no código a seguir, que foi criada uma interface que possui apenas um método, "consultar". Este método apresenta a anotação "@Get", indicando que o método será acessível diretamente via GET. A anotação "@Path" define a rota a qual este método estará escutando e, portanto, não deverão existir rotas coincidentes. A notação "@Produces(MediaType.APPLICATION_JSON)" indica a forma a qual os dados serão retornados para o cliente, neste caso conteúdo em formato Json. A notação "@Consumes(MediaType.APPLICATION_JSON)" define como os dados serão aceitos quando vindos do cliente, neste caso conteúdo em formato Json.

A classe também possui uma anotação "@Path" para definir a rota referente a ela. As demais anotações também poderiam ser anotadas diretamente na classe, o que faria com que os métodos assumissem este mesmo comportamento, exceto se eles também tivessem a anotação com uma informação diferente.


package com.joaofelipe.cep;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/cep")
public class CepService {

    @GET
    @Path("/consultar/{param1}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Endereco consultar(@PathParam("param1") int cep) {

        Endereco endereco = new Endereco();
endereco.estado = "BA"; endereco.cidade = "Salvador"; endereco.bairro = "Pituba"; return endereco; } }


Para rodar o serviço (servidor) foi utilizado o Jersey e o Grizzly, conforme exemplo a seguir:


package com.joaofelipe.cep;

import java.util.HashMap;
import java.util.Map;

import com.sun.grizzly.http.SelectorThread;
import com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory;

public class CepServicePublisher {

    public static void main(String[] args) {        
        final String baseUri = "http://localhost:7080/";
        final Map initParams = new HashMap();

        // Register the package that contains your javax.ws.rs-annotated beans here
        initParams.put("com.sun.jersey.config.property.packages","com.joaofelipe.cep");

        System.out.println("Starting grizzly...");
        try {
            SelectorThread threadSelector = GrizzlyWebContainerFactory.create(baseUri, initParams);
            System.out.println(String.format("Jersey started with WADL " + "available at %sapplication.wadl.", baseUri));
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }
}


A biblioteca Jersey pode ser baixada via maven ou diretamente pelo site:

<!-- https://mvnrepository.com/artifact/com.sun.jersey/jersey-bundle -->
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-bundle</artifactId>
    <version>1.19.2</version>
</dependency>


A biblioteca Grizzly pode ser baixada via maven ou diretamente pelo site:

<!-- https://mvnrepository.com/artifact/com.sun.grizzly/grizzly-servlet-webserver -->
<dependency>
    <groupId>com.sun.grizzly</groupId>
    <artifactId>grizzly-servlet-webserver</artifactId>
    <version>1.9.64</version>
</dependency>

Para consumir o WebService REST é possível acessar diretamente o servidor via URL, como no exemplo a seguir:


http://localhost:7080/cep/consultar/41810215


Ainda assim, é possível consumir o serviço diretamente em outro projeto, por exemplo, utilizando a biblioteca JAX-RS, podendo ser realizado da seguinte forma:


package com.joaofelipe.cep;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;

public class CepClient {

    public static void main(String[] args) {

        Endereco endereco = consultar(41810215);

        System.out.println("Estado: " + endereco.estado);
        System.out.println("Cidade: " + endereco.cidade);
        System.out.println("Bairro: " + endereco.bairro);
    }

    public static Endereco consultar(int cep) {

        Client client = ClientBuilder.newClient();

	WebTarget target = client.target("http://localhost:7080/cep/consultar/" + cep);

	Endereco endereco = target.request().get(Endereco.class);

        return endereco;
    }
}


A biblioteca JAX-RS pode ser baixada via maven ou diretamente pelo site:

<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
<dependency>
    <groupid>javax.ws.rs</groupid>
    <artifactid>javax.ws.rs-api</artifactid>
    <version>2.0</version>
</dependency>



No fim seu projeto deve ficar divido de forma semelhante a apresentada acima. Importante observar que neste exemplo o projeto "rest-common" é utilizado pelos demais projetos "rest-server" e "rest-client".

REST Java WebService

Criando e consumindo WebServices SOAP em Java


É muito comum que cada vez mais analistas optem por utilizar uma arquitetura distribuída e busquem tornar seus projetos prontos para operarem em multiplataformas. Evidentemente, existem muitas práticas necessárias para atingir este objetivo e, portanto, não se trata apenas de uma prática ou outra, mas sim o conjunto delas. Neste artigo apenas será abordado uma das tecnologias disponíveis para isso.

Para tornar mais fácil a compreensão da tecnologia, foi utilizado um exemplo de uma consulta de endereço por CEP com apenas um método com um retorno fixo simples. 


package com.joaofelipe.cep;

public class Endereco {

    public String estado;
    public String cidade;
    public String bairro;
}


Nota-se no código a seguir que foi criada uma interface que possui apenas um método, "consultar". Este método apresenta a notação "WebMethod" que indica se tratar de um método acessível do WebService. Os métodos que não possuem essa notação não serão acessíveis como métodos do WebService, mas terão comportamento normal assim como qualquer método de uma classe.

A interface também possui algumas anotações como "WebService", que indica se tratar de uma classe com comportamento de serviço web. Já a anotação "SOAPBinding(style = Style.RPC)" indica a forma como o serviço está sendo disponibilizado, neste caso, via RPC.


package com.joaofelipe.cep;
import javax.jws.WebMethod; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws.soap.SOAPBinding.Style; @WebService @SOAPBinding(style = Style.RPC) public interface CepServer { @WebMethod Endereco consultar(int cep); }


Russell Butek explica um pouco mais sobre as diferenças de estilo do SOAPBinding no developerWorks da IBM:


Before I go any further, let me clear up some confusion that many of us have stumbled over. The terminology here is very unfortunate: RPC versus document. These terms imply that the RPC style should be used for RPC programming models and that the document style should be used for document or messaging programming models. That is not the case at all. The style has nothing to do with a programming model. It merely dictates how to translate a WSDL binding to a SOAP message. Nothing more. You can use either style with any programming model.


Na classe CepServerImpl estão as implementações dos métodos da interface CepServer, apresentada acima. A anotação "WebService(endpointInterface = "com.joaofelipe.cep.CepServer")" indica o pacote e a interface do WebService.


package com.joaofelipe.cep;
import javax.jws.WebService; @WebService(endpointInterface = "com.joaofelipe.cep.CepServer") public class CepServerImpl implements CepServer { public Endereco consultar(int cep) { Endereco endereco = new Endereco(); endereco.estado = "BA"; endereco.cidade = "Salvador"; endereco.bairro = "Pituba"; return endereco; } }


Para rodar o serviço utilizamos apenas um Endpoint, pois não havia necessidade de utilizar algo com mais recursos, como um Apache Tomcat ou outro servidor qualquer. Desta forma, apenas iniciamos o serviço e deixamos ele acessível para que um cliente o consuma. Para saber um pouco mais sobre EndPoints, visite o site da Oracle em docs.oracle.com.


package com.joaofelipe.cep;
import javax.xml.ws.Endpoint; public class CepServerPublisher { public static void main(String[] args) { Endpoint.publish("http://127.0.0.1:9871/cep", new CepServerImpl()); } }


Para consumir o WebService SOAP que criamos, será preciso mapear seus métodos da seguinte forma:


package com.joaofelipe.cep;
import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; class CepClient { public static void main(String args[]) throws Exception { URL url = new URL("http://127.0.0.1:9871/cep?wsdl"); QName qname = new QName("http://cep.joaofelipe.com/","CepServerImplService"); Service ws = Service.create(url, qname); CepServer cep = ws.getPort(CepServer.class); Endereco endereco = cep.consultar(41810215); System.out.println("Estado: " + endereco.estado); System.out.println("Cidade: " + endereco.cidade); System.out.println("Bairro: " + endereco.bairro); } }


Evidentemente, o projeto onde o WebService será consumido precisa conhecer a classe Endereco e a interface que define os métodos do mesmo e, portanto, será preciso criar um projeto para ser utilizado por ambos, evitando assim duplicidade de código que ocorreria caso uma cópia da classe e da interface existisse em cada projeto, o que não deixa de ser funcional.



No fim seu projeto deve ficar divido de forma semelhante a apresentada acima. Importante observar que neste exemplo o projeto "soap-common" é utilizado pelos demais projetos "soap-server" e "soap-client".

SOAP Java WebService

Arduwin: Biblioteca Arduino para desenvolvimento de robôs


O Arduwin é uma biblioteca para desenvolvimento de dispositivos robóticos em Arduino. O projeto foi desenvolvido como forma de aprendizado e evolução do  meu conhecimento na plataforma. Alguns vídeos estão publicados no YouTube que apresentam o resultado deste projeto.


Vídeo da v.02 do projeto (atualmente estamos na v.03):



Com a primeira etapa do projeto concluída, decidi que já era o momento de compartilha-lo  de forma gratuita e acessível e, então, o publiquei no GitHub sobre a licença GNU GPL versão 2.

Copyright 2015 João Felipe Borges Portela  
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
Então, a partir de agora, será possível utilizar o projeto e entender de forma acessível como construir o seu próprio. Será possível também, através do aprendizado criar novas soluções utilizando os conceitos aplicados para o desenvolvimento Arduino e Android, como o uso de Bluetooth, ou ainda do acelerômetro.



Deixo então este espaço para apresentação de dúvidas e sugestões.

Obrigado pela atenção!

Arduwin Arduino Android Biblioteca

DataDictionaryGenerator


O DataDictionaryGenerator é gerador de dicionários de dados HTML que utiliza das informações de metadados para definir e criar o conteúdo do dicionário. O processo de geração do HTML é bem simples e, tem fluxo definido pela criação da lista de tabelas com suas respectivas descrições, para então, criar uma lista para cada tabela, apresentando as colunas e as descrições.

Atualmente é possível gerar o dicionário  apenas para o SQL Server, porém, em breve também estarão disponíveis os scripts para MySQL e PostGreSQL.

O projeto é distribuído pela MIT License: 


Copyright (c) 2015 João Felipe Portela
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


Então, pode ser utilizado para fins comerciais ou não, contanto que sejam feitos os respectivos créditos. O projeto está disponível no GitHub, segue link:

https://github.com/jfbportela/DataDictionaryGenerator

O HTML é gerado utilizando o Bootstrap, acessando-o diretamente em sua página, evitando assim precisar de arquivos além do próprio HTML gerado.

Mais informações técnicas estão disponíveis no GitHub.

GitHub 2015 DataDictionaryGenerator MIT License SQL Server MySQL PostGreSQL

Formatar String com C#


Ao exibir informações de datas, valores numéricos, valores customizados como cpf, cnpj, cep, rg, entre outros, é importante definir uma formatação adequada ao valor. Existem formatos que o .net já possuí configuração pré-definida para se ajustar conforme a "cultura", conforme exemplos a seguir:


Especificador

Tipo

Formato

Saída (Ex.: Tipo double 1.2345)

Saída (Ex.: Tipo int -12345)

c Currency (Moeda) {0:c} £1.23 -£12,345.00
d Decimal {0:d} System.FormatException -12345
e Exponencial / Formatação científica {0:e} 1.234500e+000 -1.234500e+004
f Ponto fixo {0:f} 1.23 -12345.00
g Generalizada {0:g} 1.2345 -12345
n Numérica {0:n} 1.23 -12,345.00
r Arredondado {0:r} 1.23 System.FormatException
x Hexadecimal {0:x4} System.FormatException ffffcfc7

Existem formatos customizados que permitem trabalhar de forma mais flexível, atendendo a desenvolvedores que precisam definir um formato para seu próprio uso:

Especificador

Tipo

Formato

Saída (Ex.: Tipo double 1234.56)

0 Completar com zeros {0:00.000} 1234.560
# Máscarar um número {0:#.##} 1234.56
. Posicionar o separador de decimal {0:0.0} 1234.6
, Posicionar o separador de milhar {0:0,0} 1,235
% Porcentagem {0:0%} 123456%

Um dos tipos de formatação mais usados é o de data, que por sua vez permite uma série de configurações, podendo apresentar diferentes posições de Dia, Mês e Ano, em formato reduzido, médio ou longo, com ou sem a hora entre outras definições mais específicas para Data e Hora:

É importante notar que a apresentação das datas variam conforme a Cultura (CultureInfo) definida. Para o padrão brasileiro ("pt-BR") temos o seguinte comportamento:

Especificador

Tipo

Saída (Ex.: 19 de Setembro de 1980 14:30:59)

d Data curta 19/09/1980
D Data long 19 Setembro 1980
t Hora Curta 14:30
T Hora Longa 14:30:59
f Data e Hora 19 Setembro 1980 14:30
F Data e Hora completo 19 Setembro 1980 14:30:59
g Data de Hora padrão 19/09/1980 14:30
G Data de Hora padrão longo 19/09/1980 14:30:59
M Dia / Mês 19 Setembro
r RFC1123 date string Sex, 19 Set 1980 14:30:59 GMT
s Sortable data/hora 1980-09-19T14:30:59
u Hora Universal, Timezone local 1980-09-19 14:30:59Z
Y Mês / Ano Setembro 1980

Na tabela abaixo é possível ver como formatar uma data de forma customizada:

Especificador Tipo Saída (Ex.: Setembro 19, 1980 14:30:59)
dd Dia 19
ddd Nome curto do dia Sex
dddd Nome completo do dia Sexta-feira
hh 2 dígitos para a hora 02
HH 2 dígitos para a hora (24 horas) 14
mm 2 dígitos para o minuto 30
MM Mês 09
MMM Nome curto do Mês Set
MMMM Nome do Mês Setembro
ss Segundos 59
tt AM/PM PM
yy 2 dígitos do Ano 80
yyyy 4 dígitos do Ano 1980
: Separador, ex. {0:hh:mm:ss} 14:30:59
/ Seperator, ex. {0:dd/MM/yyyy} 08/06/1970

(Este artigo foi atualizado em 08/01/2017)

C# .net