Java/ Play Framework

Play framework servindo XML e JSON ao mesmo tempo

play_framework_dicas

É comum quando você está criando sua API do zero, ter o suporte fora da caixa em JSON; Que é o padrão REST de tráfego de dados atualmente e usado por todos.

E quando sua API fala com vários players de mercado e esses players usam tecnologias diferentes? Uma boa parcela adota o JSON como padrão, já outras ainda estão amarrados ao XML. Tudo por causa do legado deixado. À exemplo disso, tem muita empresa que ainda usa Oracle 9g e 10g que não tem suporte padrão ao JSON por parte da Oracle, tendo que depender de packages de terceiros.

Teorias a parte, ainda tem muito software antigo em uso que fizeram implementação SOAP 1.1 e pararam por ai, difícil você convencer um player a mudar a sua saída para consumir nossos serviços. O interessante seria você dar a solução e criar uma interface que deixe o cliente o mais confortável possível para ele conseguir se comunicar com sua API.

Ter suporte a XML é uma forma natural de todos falarem naturalmente com seus serviços e o sucesso da integração completa é quase certo.

Enfim, o Play Framework dá suporte a saída XML e JSON nativamente fora da caixa. O problema existe quando você quer servir ambas as coisas em uma única requisição.

Para você conseguir nesse ponto, basta você interceptar qual o Content-Type da chamada e assim direcionar o uso para o formato requisitado.

package controllers;
 
import com.fasterxml.jackson.databind.node.ObjectNode;
import play.libs.Json;
import play.mvc.Controller;
import play.mvc.Result;
 
/**
 * Created by igorcosta on 14/01/15.
 */
public class BlogController extends Controller {
 
    private static final String RESPONSE_APPLICATION_XML_TYPE = "application/xml";
    private static final String RESPONSE_XML_TYPE = "text/xml";
    private static final String RESPONSE_APPLICATION_JSON_TYPE = "application/json";
 
 
    public static Result ola() {
        String headerType = request().getHeader("Content-Type");
        String retorno = null;
        if (headerType.contains(RESPONSE_APPLICATION_XML_TYPE) ||
                headerType.contains(RESPONSE_XML_TYPE)) {
 
            if (headerType.equals(RESPONSE_APPLICATION_XML_TYPE)) {
 
                response().setContentType(RESPONSE_APPLICATION_XML_TYPE);
            } else {
                response().setContentType(RESPONSE_XML_TYPE);
            }
            // Use any java lib to generate a better xml 
            retorno = "Ola Mundo";
 
        } else if (headerType.contains(RESPONSE_APPLICATION_JSON_TYPE)) {
            // Serving just plain json
            ObjectNode result = Json.newObject();
            result.put("mensagem","Ola Mundo");
            retorno = result.toString();
        }
 
        return ok(retorno);
    }
}

Screenshot from 2015-01-14 12:29:03

Você interceptando o tipo do conteúdo da chamada, você pode servir os dois formatos.

Como o Play faz o auto-generate do Header da chamada, é importante também sobrescrever o retorno da chamada, caso contrário você tem um retorno em pleo text/plain.

Dev. Software/ PHP

Implementando REST com PHP

rest_sample

Não faz muito tempo que eu escrevi sobre REST aqui no blog, e no post eu prometi que iria continuar com o assunto implementando serviços REST em diversas linguagens PHP, Java, C++, Python e até mesmo em Javascript.

Se você não sabe o que é REST, antes de continuar lendo o post, aconselho você ler o post que escrevi sobre o assunto, assim você não fica boiando no assunto.

Configurando o ambiente

Quem não tem um ambiente local para testar com PHP, sugiro um software que eu utilizo localmente o XAMPP. É open-source e grátis.
Existem outros no mercado que também faz o mesmo, só que eu gosto do XAMPP por que é prático.

Implementando o REST

Para implementar o REST você pode utilziar diversas bibliotecas espalhadas por ai, tem várias publicações e projetos que te levam à um atalho mais rápido para criar tal mecanismo. As que eu achei mais fantásticas foram essas:

O que eu acho mais fantástico nessas implementações são a abstração, eles basicamente deixam você livre para fazer o que quiser, a curva de aprendizagem também é bem mole.

O que um difere do outro?

Alguns recursos extras, por exemplo o Guzzle oferece uma arquitetura de plug-ins, onde você pode implementar suporte já fora da caixa em Cache, Oauth, etc. Já o Slim não tem tudo isso, porém oferece uma API mais simples de se dar.

Nesse exemplo eu vou usar o Slim Framework, baixe ele direto do site, depois de baixar descompacte-o no diretório raiz do XAMPP (htdocs), para ser mais direto.

rest-php

Na imagem acima, você ver que eu deixei só o diretório Slim, o arquivo .htdocs e o index.php

[note color=”#005fff”]IMPORTANTE: O Arquivo de .htaccess existente no projeto tem as regras necessárias para criação de rotas das URLs necessárias, você precisa tê-lo para usar o Slim.[/note]

Ok, abra o arquivo index e você tem o seguinte conteúdo.

<?php
/**
 * Step 1: Require the Slim Framework
 *
 * If you are not using Composer, you need to require the
 * Slim Framework and register its PSR-0 autoloader.
 *
 * If you are using Composer, you can skip this step.
 */
require 'Slim/Slim.php';
 
\Slim\Slim::registerAutoloader();
 
/**
 * Step 2: Instantiate a Slim application
 *
 * This example instantiates a Slim application using
 * its default settings. However, you will usually configure
 * your Slim application now by passing an associative array
 * of setting names and values into the application constructor.
 */
$app = new \Slim\Slim();
 
/**
 * Step 3: Define the Slim application routes
 *
 * Here we define several Slim application routes that respond
 * to appropriate HTTP request methods. In this example, the second
 * argument for `Slim::get`, `Slim::post`, `Slim::put`, and `Slim::delete`
 * is an anonymous function.
 */
 
// GET route
$app->get('/', function () {
    $template = <<<EOT
<!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8"/>
            <title>Slim Framework for PHP 5</title>
            <style>
                html,body,div,span,object,iframe,
                h1,h2,h3,h4,h5,h6,p,blockquote,pre,
                abbr,address,cite,code,
                del,dfn,em,img,ins,kbd,q,samp,
                small,strong,sub,sup,var,
                b,i,
                dl,dt,dd,ol,ul,li,
                fieldset,form,label,legend,
                table,caption,tbody,tfoot,thead,tr,th,td,
                article,aside,canvas,details,figcaption,figure,
                footer,header,hgroup,menu,nav,section,summary,
                time,mark,audio,video{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent;}
                body{line-height:1;}
                article,aside,details,figcaption,figure,
                footer,header,hgroup,menu,nav,section{display:block;}
                nav ul{list-style:none;}
                blockquote,q{quotes:none;}
                blockquote:before,blockquote:after,
                q:before,q:after{content:'';content:none;}
                a{margin:0;padding:0;font-size:100%;vertical-align:baseline;background:transparent;}
                ins{background-color:#ff9;color:#000;text-decoration:none;}
                mark{background-color:#ff9;color:#000;font-style:italic;font-weight:bold;}
                del{text-decoration:line-through;}
                abbr[title],dfn[title]{border-bottom:1px dotted;cursor:help;}
                table{border-collapse:collapse;border-spacing:0;}
                hr{display:block;height:1px;border:0;border-top:1px solid #cccccc;margin:1em 0;padding:0;}
                input,select{vertical-align:middle;}
                html{ background: #EDEDED; height: 100%; }
                body{background:#FFF;margin:0 auto;min-height:100%;padding:0 30px;width:440px;color:#666;font:14px/23px Arial,Verdana,sans-serif;}
                h1,h2,h3,p,ul,ol,form,section{margin:0 0 20px 0;}
                h1{color:#333;font-size:20px;}
                h2,h3{color:#333;font-size:14px;}
                h3{margin:0;font-size:12px;font-weight:bold;}
                ul,ol{list-style-position:inside;color:#999;}
                ul{list-style-type:square;}
                code,kbd{background:#EEE;border:1px solid #DDD;border:1px solid #DDD;border-radius:4px;-moz-border-radius:4px;-webkit-border-radius:4px;padding:0 4px;color:#666;font-size:12px;}
                pre{background:#EEE;border:1px solid #DDD;border-radius:4px;-moz-border-radius:4px;-webkit-border-radius:4px;padding:5px 10px;color:#666;font-size:12px;}
                pre code{background:transparent;border:none;padding:0;}
                a{color:#70a23e;}
                header{padding: 30px 0;text-align:center;}
            </style>
        </head>
        <body>
            <header>
                <a href="http://www.slimframework.com"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHIAAAA6CAYAAABs1g18AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABRhJREFUeNrsXY+VsjAMR98twAo6Ao4gI+gIOIKOgCPICDoCjCAjXFdgha+5C3dcv/QfFB5i8h5PD21Bfk3yS9L2VpGnlGW5kS9wJMTHNRxpmjYRy6SycgRvL18OeMQOTYQ8HvIoJKiiz43hgHkq1zvK/h6e/TyJQXeV/VyWBOSHA4C5RvtMAiCc4ZB9FPjgRI8+YuKcrySO515a1hoAY3nc4G2AH52BZsn+MjaAEwIJICKAIR889HljMCcyrR0QE4v/q/BVBQva7Q1tAczG18+x+PvIswHEAslLbfGrMZKiXEOMAMy6LwlisQCJLPFMfKdBtli5dIihRyH7A627Iaiq5sJ1ThP9xoIgSdWSNVIHYmrTQgOgRyRNqm/M5PnrFFopr3F6B41cd8whRUSufUBU5EL4U93AYRnIWimCIiSI1wAaAZpJ9bPnxx8eyI3Gt4QybwWa6T/BvbQECUMQFkhd3jSkPFgrxwcynuBaNT/u6eJIlbGOBWSNIUDFEIwPZFAtBfYrfeIOSRSXuUYCsprCXwUIZWYnmEhJFMIocMDWjn206c2EsGLCJd42aWSyBNMnHxLEq7niMrY2qyDbQUbqrrTbwUPtxN1ZZCitQV4ZSd6DyoxhmRD6OFjuRUS/KdLGRHYowJZaqYgjt9Lchmi3QYA/cXBsHK6VfWNR5jgA1DLhwfFe4HqfODBpINEECCLO47LT/+HSvSd/OCOgQ8qE0DbHQUBqpC4BkKMPYPkFY4iAJXhGAYr1qmaqQDbECCg5A2NMchzR567aA4xcRKclI405Bmt46vYD7/Gcjqfk6GP/kh1wovIDSHDfiAs/8bOCQ4cf4qMt7eH5Cucr3S0aWGFfjdLHD8EhCFvXQlSqRrY5UV2O9cfZtk77jUFMXeqzCEZqSK4ICkSin2tE12/3rbVcE41OBjBjBPSdJ1N5lfYQpIuhr8axnyIy5KvXmkYnw8VbcwtTNj7fDNCmT2kPQXA+bxpEXkB21HlnSQq0gD67jnfh5KavVJa/XQYEFSaagWwbgjNA+ywstLpEWTKgc5gwVpsyO1bTII+tA6B7BPS+0PiznuM9gPKsPVXbFdADMtwbJxSmkXWfRh6AZhyyzBjIHoDmnCGaMZAKjd5hyNJYCBGDOVcg28AXQ5atAVDO3c4dSALQnYblfa3M4kc/cyA7gMIUBQCTyl4kugIpy8yA7ACqK8Uwk30lIFGOEV3rPDAELwQkr/9YjkaCPDQhCcsrAYlF1v8W8jAEYeQDY7qn6tNGWudfq+YUEr6uq6FZzBpJMUfWFDatLHMCciw2mRC+k81qCCA1DzK4aUVfrJpxnloZWCPVnOgYy8L3GvKjE96HpweQoy7iwVQclVutLOEKJxA8gaRCjSzgNI2zhh3bQhzBCQQPIHGaHaUd96GJbZz3Smmjy16u6j3FuKyNxcBarxqWWfYFE0tVVO1Rl3t1Mb05V00MQCJ71YHpNaMcsjWAfkQvPPkaNC7LqTG7JAhGXTKYf+VDeXAX9IvURoAwtTFHvyYIxtnd5tPkywrPafcwbeSuGVwFau3b76NO7SHQrvqhfFE8kM0Wvpv8gVYiYBlxL+fW/34bgP6bIC7JR7YPDubcHCPzIp4+cum7U6NlhZgK7lua3KGLeFwE2m+HblDYWSHG2SAfINuwBBfxbJEIuWZbBH4fAExD7cvaGVyXyH0dhiAYc92z3ZDfUVv+jgb8HrHy7WVO/8BFcy9vuTz+nwADAGnOR39Yg/QkAAAAAElFTkSuQmCC" alt="Slim"/></a>
            </header>
            <h1>Welcome to Slim!</h1>
            <p>
                Congratulations! Your Slim application is running. If this is
                your first time using Slim, start with this <a href="http://www.slimframework.com/learn" target="_blank">"Hello World" Tutorial</a>.
            </p>
            <section>
                <h2>Get Started</h2>
                <ol>
                    <li>The application code is in <code>index.php</code></li>
                    <li>Read the <a href="http://docs.slimframework.com/" target="_blank">online documentation</a></li>
                    <li>Follow <a href="http://www.twitter.com/slimphp" target="_blank">@slimphp</a> on Twitter</li>
                </ol>
            </section>
            <section>
                <h2>Slim Framework Community</h2>
 
                <h3>Support Forum and Knowledge Base</h3>
                <p>
                    Visit the <a href="http://help.slimframework.com" target="_blank">Slim support forum and knowledge base</a>
                    to read announcements, chat with fellow Slim users, ask questions, help others, or show off your cool
                    Slim Framework apps.
                </p>
 
                <h3>Twitter</h3>
                <p>
                    Follow <a href="http://www.twitter.com/slimphp" target="_blank">@slimphp</a> on Twitter to receive the very latest news
                    and updates about the framework.
                </p>
            </section>
            <section style="padding-bottom: 20px">
                <h2>Slim Framework Extras</h2>
                <p>
                    Custom View classes for Smarty, Twig, Mustache, and other template
                    frameworks are available online in a separate repository.
                </p>
                <p><a href="https://github.com/codeguy/Slim-Extras" target="_blank">Browse the Extras Repository</a></p>
            </section>
        </body>
    </html>
EOT;
    echo $template;
});
 
// POST route
$app->post('/post', function () {
    echo 'This is a POST route';
});
 
// PUT route
$app->put('/put', function () {
    echo 'This is a PUT route';
});
 
// DELETE route
$app->delete('/delete', function () {
    echo 'This is a DELETE route';
});
 
/**
 * Step 4: Run the Slim application
 *
 * This method should be called last. This executes the Slim application
 * and returns the HTTP response to the HTTP client.
 */
$app->run();

Mude-o para isso aqui.

<?php
require 'Slim/Slim.php'; // chamando a biblioteca
 
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim(); // registrando e inicializando o objeto no servidor
 
 
// GET route
$app->get('/', function () {
    $template = <<<EOT
        <h1>Implementando REST com slim framework</h1>
EOT;
    echo $template;
});
 
// POST route
$app->post('/post', function () {
    echo 'This is a POST route';
});
 
// PUT route
$app->put('/put', function () {
    echo 'This is a PUT route';
});
 
// DELETE route
$app->delete('/delete', function () {
    echo 'This is a DELETE route';
});
 
$app->run();

O que eu fiz foi remover os comentários excessivos que tinha no arquivo e coloquei uma mensagem customizada para mostrar que roda tranquilamente.

Toda vez que você for implementar um novo método no Slim Framework, basta você definir que tipo de comportamento ele possui e a ação que ele irá fazer.

Por exemplo quero criar um novo método chamado calcular.

$app->post('/calcular/:metodo',function($metodo) use ($app){
 
        $request = $app->request();
        $body = $request->post();
 
    switch($metodo){
            case 'somar':
                        echo $body['A'] + $body['B'];
            break;
            case 'dividir':
                        echo $body['A'] / $body['B'];
            break;
            case 'multiplicar':
                        echo $body['A'] * $body['B'];
            break;
            case 'diminuir':
                        echo $body['A'] - $body['B'];
            break;
    }
});

Eu posso usar as URIs com os métodos (/put, /post, /get, /delete).

E para testar meu serviço de REST como faço? Bom, você pode usar o cURL ou usar uma GUI para facilitar o processo, já que eu estou utilizando o navegador, eu vou adicionar uma extensão para o Google Chrome fazer isso. POSTMAN para nos salvar.

rest-gui

Na Webstore do google procure pelo POST MAN e você acha ele fácil, basta clicar em instalar e começar a testar.

rest-gui-demo

Coloco a URL, passo os parametros e voilá! Meu serviço de REST está implementado.

E como fica a requisição do servidor na aba de acesso? Vamos ver!

rest-php-call

Perfeito, eu posso criar vários serviços Web sem precisar escrever uma interface própria para testar, não existe mais desculpas esfarrapadas de esperar o Designer terminar a conversão de PSD para HTML/CSS para você começar a testar os serviços.

Esse é um belo exemplo simples de como implementar um serviço de REST. Agora vamos para um exemplo prático, digo mais completo.

Nesse exemplo usei o SQlite 3 para persistir os dados, você pode usar o que você quiser para persistência em PHP, o Slim não implica o uso de nenhum, já que dentro de suas chaves você pode escrever o que quiser.

[note color=”#007bff”]SQLite 3 só é suportado no PHP 5.4 em diante. Versões anteriores você pode usar o SQLite 2. Para saber qual versão que você tem use o php_info();[/note]

É bem simples o serviço de REST com uma API bem simplificada. O código abaixo contém as seguintes rotas que usaremos para o serviço.

  • GET /preload-inicial – Uso ele só 1 vez para carregar com dados falsos para ter algo para mostrar
  • GET /backup – Faz backup do banco
  • GET /clientes – Lista todos os clientes
  • GET /compras – Lista todas as compras do site
  • GET /compras/:id – Lista todas as compras de um cliente especifico pelo ID
  • PUT /cliente – Adicionar novos clientes
  • PUT /compra – Adicionar novas compras
  • POST /cliente/:id – Atualiza o cliente pelo ID
  • POST /compra/:id – Atualiza uma compra pelo ID
<?php
require 'Slim/Slim.php';
 
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();
 
$response =array();
$db = new SQLite3('coisas.db');
 
 
// Uso essa função só para gerar dados fakes para ser usado no sistema
$app->get('/preload-inicial', function () use ($db,$response)
{       $value = rand(5,99);
        $db->exec('CREATE TABLE IF NOT EXISTS clientes(id INTEGER PRIMARY KEY AUTOINCREMENT, nome TEXT);');
        $db->exec('CREATE TABLE IF NOT EXISTS compras(id INTEGER PRIMARY KEY, cliente_id INTEGER, valor INTEGER, compra_realizada DATETIME);');
        $db->query("INSERT OR IGNORE INTO clientes (nome) VALUES ('Igor Costa');");
        $db->query("INSERT OR IGNORE INTO clientes (nome) VALUES ('Elly Costa');");
        $db->query("INSERT OR IGNORE INTO clientes (nome) VALUES ('Leonardo Sobral');");
        $db->query("INSERT OR IGNORE INTO clientes (nome) VALUES ('Francisco Brianezi');");
        for($i=1;$i<=4;$i++){
            $db->query("INSERT INTO compras (valor,cliente_id,compra_realizada) VALUES ($value,$i,datetime());");
        }
 
});
// adicionar cliente
$app->put('/cliente', function () use($db,$response,$app) {
    $request = $app->request();
    $cliente = $request->put('nome');
    $response =$db->exec("INSERT INTO clientes (nome) VALUES ('$cliente');");
    echo $response;
});
// adicionar nova compra
$app->put('/compra', function () use($db,$response,$app) {
    $request = $app->request();
    $valor = $request->put('valor');
    $cliente = $request->put('cliente_id');
    $response = $db->query("INSERT INTO compras (valor,cliente_id,compra_realizada) VALUES ($valor,$cliente,datetime());");
    echo $response;
});
 
 
// Ediar cliente
 
$app->post('/cliente/:id',function($id) use($db,$response,$app){
    $request = $app->request();
    $nome = $request->post('nome');
    $response = $db->exec("UPDATE clientes SET nome='$nome' WHERE id=$id;");
    echo json_encode($response);
});
 
$app->post('/compra/:id',function($id) use($db,$response,$app){
    $request = $app->request();
    $valor = $request->post('valor');
    $cliente = $request->post('cliente_id');
    $response = $db->exec("UPDATE compras SET valor='$valor', cliente_id='$cliente' WHERE id=$id;");
    echo json_encode($response);
});
 
// lista os clientes
$app->get('/clientes',function()use ($db,$response,$app){
 
   $app->contentType('application/json');
   $tarefas = $db->query("SELECT * FROM clientes");
        while ($row = $tarefas->fetchArray(SQLITE3_ASSOC)) {
            array_push($response,$row);
        }
      echo json_encode($response);
 
});
// lista todas as compras
$app->get('/compras',function() use($db,$response,$app){
   $app->contentType('application/json');
   $tarefas = $db->query("SELECT clientes.id,clientes.nome,COUNT(*) as total_compras
                          FROM compras INNER JOIN clientes ON compras.cliente_id = clientes.id 
                          GROUP BY clientes.nome ORDER BY clientes.nome ASC");
        while ($row = $tarefas->fetchArray(SQLITE3_ASSOC)) {
            array_push($response,$row);
        }
      echo json_encode($response);
 
});
// lista todas as compras por id do cliente
$app->get('/compras/:id',function($id) use ($db,$response){
 
    $tarefas = $db->query("SELECT * FROM compras INNER JOIN clientes 
        ON compras.cliente_id = clientes.id  WHERE clientes.id = $id");
        while ($row = $tarefas->fetchArray(SQLITE3_ASSOC)) {
            array_push($response,$row);
        }
      echo json_encode($response); 
});
$app->get('/backup',function() use($app){
    $date = date("Y-m-d");
    exec('mkdir backups');
    $file = 'backups/backup-'.$date . '.sql';
    exec("sqlite3 coisas.db .dump > ".$file);
    echo readfile($file);
});
 
// Deleta cliente
$app->delete('/deleta/cliente/:id', function ($id) use ($db,$response,$app) {
 
    // para remover compras existentes do cliente
    $db->exec("DELETE FROM compras WHERE cliente_id=$id;");
    $response =$db->query("DELETE FROM clientes WHERE id=$id;");
    echo $response; 
});
// Deleta compra
$app->delete('/deleta/compra/:id', function ($id) {
    $response =$db->query("DELETE FROM compras WHERE id=$id;");
    echo $response; 
});
 
$app->run();

Para consumir esse serviço você pode usar a seguinte interface.

rest-gui-php-demo

Agora você já sabe como implementar um serviço em RESTful com PHP usando o Slim Framework. Na próxima competição que você participar use algo assim, é hiper rápido e você não gasta mais que 1 hora para implementar.

O uso do SQLite eu aconselho para coisas bem simples, listas simples e pouco à médio volume de dados. Não queria criar um ERP com SQLite que você está perdendo seu tempo.

Para maiores detalhes sobre o Slim Framework, visite a documentação do projeto. É simples e bem intuitiva.

O código fonte está disponível também no Github.

Actionscript Frameworks/ AS 3.0/ Flex/ frameworks/ Notícias/ Web 2.0

Boo-Box Actionscript 3.0 API para Flash/Flex

Opa, estamos felizes por ajudar mais uma vez ao mundo open-source e toda comunidade Flash/Flex brasileira.


Alguém aqui conhece o Boo-Box?

Boo-Box, é um serviço de agregação de produtos on-line que geram renda para você blogueiro, dono de site, é um mix de serviços de afiliados em um só lugar. Por exemplo eles oferecem um serviço que é único para acessar produtos de lojas como a submarino, americanas.com,mercado livre, dentre outros sites internacionais como todos as lojas do amazon,e-bay,etc. Tudo no bom estilo web 2.0.

Está ai entre poucos sites que oferecem API tupiniquem para seus serviços, modelo o qual muito portal e serviço web brasileiro deveriam adotar.

Até então a única api existente para o Boo-Box é em REST(xml/JSON). Por que não portar uma API para o lado cliente e mais ainda para o Flex/Flash.

A API do Boo-Box para actionscript 3.0 é completa, tem todos os serviços que a Boo-Box oferece.

Você só precisar ir no http://code.google.com/p/booboxas3api/

No projeto do google você encontra o SWC para integrar dentro de seu projeto Flash ou Flex, exemplos, documentação da API, tudo para facilitar sua vida.

Agora começe a ganhar dinheiro com suas aplicações Flex ou criar uma loja para isso.

Actionscript/ AS 3.0/ Flex Componentes/ Google

Criando sua primeira aplicação com o Google Maps AS3.0 API

Continuando depois do último post feito sobre esse estupendo, helvis,…, igual ao rapaz de Quixeramobim, Ceará. Vamos aos passos.

Antes de começar a ler o resto do post e bateu a preguiça de ler? Bom, eu pensei nisso também, então tá aqui a solução pronta.

Primeiro passo

Gere uma Google Map API Key para ter acesso externo aos mapas do google. Como? Clique aqui.

O que é esse Google Map API Key?
É um controle que o google faz para saber quantas aplicações ou acessos estão sendo feito em suas aplicações para servir como referência de suas pesquesas.
O Principal objetivo do GMA Key é justamente deixar você usar o serviço sem precisar autenticá-lo toda vez que for usar.
Não existe limitação de uso ou qualquer outra forma de bloqueio, porém o google pede que se o seu aplicativo tiver mais que 500mil pageview que entre em contato com eles para eles poderem te ajudar melhor nisso aumentando sua capacidade para que seu serviço não sofra com isso.

Aceite os termos do contrato, após isso submeta uma URL para que o google saiba onde será localizado o aplicativo, por exemplo você pode colocar apenas o site da sua empresa ou seu sem precisar especificar ao certo qual path(diretório) será guardado o aplicativo.

Copie o código que o Google vai lhe dar, geralmente é um conjunto imenso de caracteres, procure guardar em um bloco de notas da vida.

Minha chave de código é essa:

1
ABQIAAAAfRPIvINtjZu3PtRGVoq7mBQogceLfcZe7FekjL-2SpDGGlJNIRRAbExTAlOd6Y5xk8V9kGtfjzffFw

Mesmo eu colocando aqui publicamente a chave ela só funcionará no meu domínio, uma forma de proteger o serviço para cada domínio.

Lembre-se que não é necessário ter uma conta do Google para fazer isso, o que é mais legal ainda.

Segundo passo

Baixe o SDK do Google

O SDK do Google Maps As3.0 API, contém documentação de todas suas classes e um .swc que tanto pode ser usado no Flash quanto no Flex, por ambos os produtos suportarem a linguagem Actionscript 3.0.
Caso você esteja lendo esse post e usa Flash, espere por outro tutorial voltado para Flash, já que esse aqui será voltado apenas para desenvolvedores Flex.

Feito o Download do pacote que é um arquevo *.zip, por favor descompacte usando algum software .zip, supondo eu que aqui só tenha desenvolvedores ou aspirantes de desenvolvedores, obviamente maior parte aqui sabe usar um descompactador.

Hora de ir para o Flex Builder.

1. Crie um projeto Novo no Flex Builder
2. Nomeie o projeto como GoogleFlexMap
3. Clique em Finish

Na estrutura de diretório do projeto criado existe uma pasta chamada Libs, dentro dessa pasta você vai jogar o arquevo map_flex_1_1.swc que você estraiu do arquevo SDK zipado.
Não precisa de tanto detalhe basta copiar o arquevo, selecionar a pasta e dá um simples CTRL+V.

Feito isso, seu projeto vai suportar a API do Google Maps. Hora de começar a Programar.

Crie uma nova classe em AS3.0 no Flex. Para criar siga os passos:
1. File > New > Actionscript Class
2. Use o Package para a classe de seu gosto, eu usei o com.igorcosta
3. Por regra de convenção Classes em Actionscript é mais aceitas a primeira letra ser Maiúscula
4. Nomeie para GoogleFlexMap
5. Estenda o GoogleFlexMap usando o SuperClass, clique em Browser e escolha UIComponent para ser estendida.
6. Clique em OK

Se você seguiu tudo certo, você terá um novo arquevo gerado com a seguinte sintaxe.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
package com.igorcosta
{
	import mx.core.UIComponent;
 
	public class GoogleFlexMap extends UIComponent
	{
		public function GoogleFlexMap()
		{
			super();
		}
 
	}
}

Nota: Como o google criou uma API genérica para Flash/Flex você vai precisar usar esse tipo de artifício para garantir que ele será adicionado a classe UIComponent que faz uso de criar controles da tela.

Então para encurtar mais eu fiz uma classe simples que vai definir um novo Componente no qual terá o nome definido de GoogleFlexMap igual a classe criada.

Segue a classe completa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
 
package com.igorcosta
{
	import com.google.maps.LatLng;
	import com.google.maps.Map;
	import com.google.maps.MapEvent;
	import com.google.maps.MapType;
	import com.google.maps.controls.MapTypeControl;
	import com.google.maps.controls.PositionControl;
	import com.google.maps.controls.ZoomControl;
 
	import flash.events.Event;
	import flash.geom.Point;
 
	import mx.core.UIComponent;
	import mx.events.FlexEvent;
 
	public class GoogleFlexMap extends UIComponent
	{
 
		private var _largura:Number = 650;
		private var _altura:Number = 500;
		private var _mapa:Map;
		private var _tipomapa:Array = ["hibrido","normal","fisico","satelite"];
		private var _key:String;
		private var _controleZoom:Boolean = false;
		private var _controlePosicao:Boolean = false;
		private var _controleTipo:Boolean = false;
 
		public function GoogleFlexMap()
		{
			super();
			super.addEventListener(FlexEvent.INITIALIZE,init);
 
		}
		private function init(event:Event):void {
			 this.width = _largura;
			this.height = _altura;
			// Iniciando o Objeto Map
			_mapa = new Map();
			_mapa.key =_key;
			_mapa.addEventListener(MapEvent.MAP_READY,criarUIMapa);
			_mapa.setSize( new Point (this.width, this.height));
				if(_controleZoom){
				_mapa.addControl( new ZoomControl());
				}
				if(_controleTipo){
					_mapa.addControl(new PositionControl());
				}
				if(_controleTipo){
					_mapa.addControl(new MapTypeControl());
				}
			// adiciona o _mapa ao UIComponent;
			this.addChild(_mapa);
		}
		public function get ControleZoom():Boolean{
			return _controleZoom;
		}
		public function set ControleZoom(value:Boolean):void {
			_controleZoom = value;
		}
		public function get ControlePosicao():Boolean{
			return _controlePosicao;
		}
		public function set ControlePosicao(value:Boolean):void {
			_controlePosicao = value;
		}
		public function get ControleTipo():Boolean {
			return _controleTipo;
		}
		public function set ControleTipo(value:Boolean):void {
			_controleTipo = value;
 
		}
		public function get key():String{
				return _key;
		}
		public function set key(value:String):void {
			_key = value;
		}
		private function criarUIMapa(event:Event):void {
			_mapa.setCenter( new LatLng(40.736072,-73.992062),14,MapType.HYBRID_MAP_TYPE);
		}
	}
}

A classe facilita muito o uso. Então ela tem propriedades específicas que faz fácil o uso.

Terceiro Passo

Usando o Componente criado

Simplesmente você fará assim

1
2
3
4
5
6
7
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:google="com.igorcosta.*"  xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
  	<google :GoogleFlexMap
  		key="ABQIAAAAfRPIvINtjZu3PtRGVoq7mBQogceLfcZe7FekjL-2SpDGGlJNIRRAbExTAlOd6Y5xk8V9kGtfjzffFw"
  		width="100%" height="100%"/>
</mx>

Feito, você verá um resultado bem mais simples. Fácil não é?

[ATUALIZADO]

Como sempre a pressa é inimiga da perfeição, Fiz algumas alterações na classe e coloquei agora mais controles de forma mais fácil.

Tá com preguiça de fazer tudo isso? Baixe aqui o projeto completo feito.

Actionscript Frameworks/ AS 3.0/ Flex/ frameworks/ Google/ Open-source/ Web 2.0

Google Maps Actionscript 3.0 API Finalmente

Finalmente o tão aguardado, flamigerado e esperado por todos que trabalham com a plataforma Flash Player ( Flex/Flash/AIR), esperaram por essa grande notícia no última conferência Where 2.0 em San Francisco,US.

Google finalmente ajudou e muito a comunidade deixando de lado um pouco o aspecto de criar apenas para AJAX ou HTML.

Anterior à isso só existiam 2 produtos o UMap que usa o OpenMaps e Microsoft Map e o do Yahoo!.

O grande problema desses mapas é que para o Brasil fica muito restrito o acesso e não tem tanta riqueza de detalhes como o Google possui.

No próximo post, vocês vão ver como montar o ambiente, ou melhor projeto para começar a criar.