play_framework_dicas

Play framework servindo XML e JSON ao mesmo tempo

É 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.

foot_steps

Feliz Natal e Ano Novo

Chegamos à praticamente mais um final de ano, todos recebem aqueles cartõezinhos sem sentidos e automáticos de listas de opt-in, alguns recebem descontos de 10% de ofertas para produtos que não tem necessidade e outros se manifestam em blogs, escrevendo pseudos textos para distrair a mente e desejar um feliz natal para seus fiéis leitores.

2014 Foi um ano turbulento, com fortes mudanças de vida, mudei de cidade, mudei de emprego, renovei os conhecimentos, aprendi 2 novos idiomas (Chinês e Japonês), não como gostaria, seria um pouco soberbo em achar que dominaria todo por completo. O básico para guia do viajante eu já sei, o que é de bom tamanho. Se eu falhar tem o inglês sempre que me salva.

Mudei completamente o foco do blog, prometi escrever mais, só que devido a tanta mudança tentei ser o mais pontual possível nos posts por aqui. Embora tenha mudado, consegui ainda escrever uma média de 3 artigos por mês.

Se for aplicar a matemática humana, fiz muita coisa e coisas boas. A vida em São Paulo é totalmente diferente da vida que eu vivia, ser empregado é uma nova experiência, é algo que estou aprendendo constantemente. Deixei de lado um pouco eventos, embora convites não fosse feito, eu preferir evitar e focar nessa nova jornada, sabe aquela coisa foque no que você é bom.

Cai de cabeça dentro dos estudos, compartilhei em alguns videos no youtube um pouco do que aprendi, ganhei milhares de admiradores e fiz novos amigos.

Um agradecimento em especial as pessoas que fizeram a diferença em meu 2014:

Alexandre Salomão, Jennifer Lee Palmer, Merlise Rupolo, Daniele Alves, Rodrigo Kfouri, Orsi, Miguel Damasceno, Fabricio Costa, David Ruiz, Marcelo Santos, William Amaro, Gustavo Lopez, Alexandre Telles, Cassiano Alves, Cid Moreira, Luciana Carvalho, Lucas Melman, Igor Minar, Robert Nyman, Aral Balkan, Alex Harui, Fabio Magnoni, Eduardo Magno, Wesley Valentim, Elizangela, Pollyana Damasceno, Heider Lopes, Mariana Fullen, Sergio Cabral, Thiago Baeta, Cezar Xavier, Larissa Lima, Rafael B Lopes, Dona Sônia, Wender Lima (Grande Brother), Alexandre Grillo, Rafael Nami, Carlos Gatto, Mariana Villas Lobo, Lucas Alves, Larissa Medeiros, Thiago Medeiros, Marcus Pinto, Plínio Fabricio Alencar, Minha Familia, Todos os leitores do blog, Todos que assistiram aos videos no youtube.

Todos que estão ai em cima impactaram positivamente meu 2014.

Desejo a todos vocês um feliz natal e em uma frase bem simples: “Nunca deixe de acreditar em si mesmo”.

wired

Habilitando CORS no Play Framework 2.3.x

É bem comum quando você trabalha com diferentes servidores e recursos separados por uma vasta rede de servidores, ou você contorna isso usando Nginx, proxies ou você implementa uma abordagem diferente quando chega nesse nível.

CORS, basicamente é o problema mais comum em lhe dar com chamadas AJAX hoje em dia, por exemplo esse post foi inspirado nessa necessidade.

No Play Framework você samba um pouquinho para conseguir adicionar suporte a CORS nas chamadas que forem executadas por lá.

Para quem usa Tomcat, pode usar o filtro que o Ebay disponibilizou no Github.

Como funciona no Play?

Crie um arquivo na pasta Raiz:Global.java

 
import play.GlobalSettings;
import play.libs.F.Promise;
import play.mvc.Action;
import play.mvc.Http;
import play.mvc.SimpleResult;
 
public class Global extends GlobalSettings {
    private class ActionWrapper extends Action.Simple {
        public ActionWrapper(Action<?> action) {
            this.delegate = action;
        }
 
        @Override
        public Promise<SimpleResult> call(Http.Context ctx) throws java.lang.Throwable {
            Promise<SimpleResult> result = this.delegate.call(ctx);
            Http.Response response = ctx.response();
            response.setHeader("Access-Control-Allow-Origin","*");
            response.setHeader("Access-Control-Allow-Methods", "POST, HEAD, PATCH, GET, PUT, DELETE, OPTIONS");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
            return result;
        }
    }
 
    @Override
    public Action<?> onRequest(Http.Request request, java.lang.reflect.Method actionMethod) {
        return new ActionWrapper(super.onRequest(request, actionMethod));
    }
}

Salve e execute qualquer chamada REST que você tenha de serviço no Play, o cabeçalho agora aparecerá para você assim:

 
 
    Status Code: 200 OK
    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization
    Access-Control-Allow-Methods: POST, HEAD, PATCH, GET, PUT, DELETE, OPTIONS
    Access-Control-Allow-Origin: *
    Content-Length: 3322
    Content-Type: application/json; charset=utf-8

Fácil né? Para chegar até aqui foi complicado, então deixo aqui o registro para futuros devs Java que tiverem esses problemas para resolver de forma mais rápida que eu.

Até o próximo post, dúvidas, deixem seus comentários.

gitignore_site

.gitignore e como gerar o seu

Esse é um post rápido, se você tem um projeto e que faz versionamento com o Git, sempre terá que ignorar alguns arquivos como: preferências de (sdk, projeto), saída do projeto, arquivos de documentação. Em fim tem de tudo um pouco para você gerenciar.

O que mais complica é quando você tem N IDEs,com um time que tem diferentes skills e que usam diferentes IDE para trabalhar, nesse ponto você tem que alterar com certa frequência o .gitignore para levar em consideração e não entrar arquivos indesejáveis.

A melhor maneira de fazer isso é com auxílio. Achei um site bem bacana para isso.

www.gitignore.io

O site gitignore.io é excelente, consigo facilmente adicionar os arquivos para serem ignorados. Diminuindo a chance de erros.

Welcome - Polymer

Gravação Componentizando a Web com Polymer

No último sábado aconteceu outro Hangout da série tecnologias Google para desenvolvimento Web.

Eu particularmente estou adorando a receptividade do público que está fomento por tanto conteúdo.

Nesse hangout eu mostrei um pouco sobre componentes Web, arquitetura do Polymer e como ele pode resolver alguns problemas já existentes.

Quem quiser assistir, está on-line a gravação no youtube.

Código fontes e slides são disponíveis pela licença Creative Commons, significa que você pode modificar e mencionar a fonte original, com isso você pode fazer a mesma apresentação no seu grupo de usuários, estudos etc.

Slides: Baixar Slides

Exemplos criados no Hangout:
Fork no Github

Aproveito e faço o convite para os próximos que sempre acontecem na última semana de cada mês.

Quem perdeu também o hangout sobre AngularJS, pode assistir aqui.

Welcome - Polymer

Hangout – Componentizando a Web com Polymer

No próximo sábado (25/10) 01/Novembro , vamos nos reunir on-line e apresentar para vocês toda essa idéia de componentização da Web com o framework Polymer.

Assim como no mês passado, foi um sucesso mesmo com a minha baita bronquigripe acabou saindo algo bom e que o pessoal curtiu para caramba.

Dessa vez eu consegui caprichar mais e com toda certeza vai ser melhor que o último hangout.

Convide seus amigos, compartilhe nas redes sociais, é grátis e dura em média 2 ou 3 horas.

Remarcamos para uma melhor experiência.

angular-hangout

Gravação do hangout criando Web Apps com AngularJS

Agradeço aos mais de 167 participantes de assistiram ao vivo o Hangout e aos mais de 760 que já assistiram a gravação até o momento da escrita desse post.

Quem perdeu, pode assistir no youtube a gravação.

Mesmo com uma forte gripe que me arrastou para uma bronquite aguda, consegui explicar em um estilo de aula, como você pode se tornar produtivo com o AngularJS, assim como, usando o Bower, Yeoman e Grunt para automatizar as tarefas.

angular-hangout

Convite para participar do Hangout Web Apps com AngularJS

Chegou a hora de compartilhar o que aprendi nos últimos 12 meses.

Convido todos vocês leitores a aprender um pouco sobre como criar Web Apps com AngularJS nesse Hangout on-line e grátis.

Será no próximo sábado as 09:30 da manhã horário de Brasilia, e com uma duração máxima de 3 horas.

Nesse hangout como é de costume, vou comentar sobre as semelhanças do Flex com o Angular, arquitetura de uma Web App e consumindo serviços REST de forma mais fácil.

A transmissão também será gravada e disponibilizada no Youtube.

angular_header

AngularJS extensões para Chrome e Firefox

Duas extensões que fazem uma tremenda diferença para quem desenvolve para Web com algum editor simples como o SublimeText ou Atom.

Batarang para o Chrome

batarang

Angscope para Firefox

ngscope

Se você usa uma IDE mais completa como o WebStorm, você pode instalar um plugin para o Chrome do JetBrains e debugar direto.

Independente de IDE, uma boa ferramenta para explorar o scope de cada controller e diretiva é definitivamente melhor que usar o console.log(); para debugar suas próximas aplicações.

angular_header

Angular 1.2.x One-Way data-binding

A grande vantagem do AngularJS é o two-way data-binding. Embora isso seja uma excelente função, em excesso acaba causando problemas, dentre eles performance para renderizar valores.

E isso impacta diretamente na questão de Grids de dados, internacionalização, gráficos e por ai adiante.

Boa parte de aplicações usa apenas one-way data-binding, já que é parte pertinente só renderizar dados, quando se exige um certo nível de aceitação para intergir, consumir um websocket ou atualizações constantes o two-way é a solução perfeita para isso.

A atual versão do angular 1.2.24 só possui suporte ao two-way data-binding. Qual a solução para o problema? Criar uma diretiva que permita o uso apenas de uma maneira.

Entendendo o problema

Sempre que você assina o two-way com {{ }} em suas views de HTML, o angular cria uma raiz de eventos para observar se o valor vai mudar ou não, consequentemente atualizar a view.

 
     <p>Olá {{USER_NAME}}</p>

O $watch faz esse papel, criando isso em pequenas aplicações é até aceitável, já que o nível de controle é sustentável e não existe tantas variáveis sendo mudada.

Criando a diretiva One-way

var app = angular.module("OneWayApp",[]);
 
app.directive('oneWay', function() {
    return {
        scope: true,
        link: function($scope,$elm) {
            setTimeout(function() {
                $scope.$destroy();
                $elm.removeClass('ng-binding ng-scope');
            }, 0);
        }
    }
});

O que eu faço é só destruir o $watcher depois que o valor for renderizado na view, assim evito ficar olhando por mudanças que não são necessárias.

Veja um exemplo sendo executado abaixo.

One-way App

Performaticamente falando, consigo renderizar 10 mil itens na tela sem precisa olhar todos eles, tire o atributo one-way e seu Brower pode quebrar e fechar. Até a barra de rolagem fica mais suave com tantos itens sem precisa observar suas mudanças.Igor Costa

Futuro do Angular JS

Essa função vai vim built-in na próxima versão do AngularJS 1.3.

Sua anotação será da seguinte forma:

 
<p>{{::user.name}}</p>

Colocando só os ::, essa função quem quiser se arriscar na RC-1, pode usar em seus projetos futuros, embora quem ainda dependa muito de funções especificas do 1.2.x, pode usar essa diretiva.

Desenvolvimento de software para Web e Mobilidade