qcon 2015 - combinando angularjs com java ee

57
Combinando AngularJS com Java EE Rodrigo Cândido da Silva @rcandidosilva

Upload: rodrigo-candido-da-silva

Post on 13-Apr-2017

1.318 views

Category:

Software


2 download

TRANSCRIPT

Page 1: QCon 2015 - Combinando AngularJS com Java EE

Combinando AngularJS com Java EERodrigo Cândido da Silva @rcandidosilva

Page 2: QCon 2015 - Combinando AngularJS com Java EE

About Me• Software Architect

• http://integritastech.com • JUG Leader do GUJavaSC

• http://gujavasc.org • Twitter

• @rcandidosilva • Contatos

• http://rodrigocandido.me

Page 3: QCon 2015 - Combinando AngularJS com Java EE

Agenda• Arquitetura Rich Client • RESTful Web Services • Java EE 7

• JAX-RS • WebSocket • JSON-P

• AngularJS • Demo

Page 4: QCon 2015 - Combinando AngularJS com Java EE

Client-side vs. Server-side• Server-side

• Tudo é processado no servidor

• Mais stateful • Fraca escalabilidade

• Client-side • Complexo e dinâmico • Mais stateless • Maior escalabilidade

Page 5: QCon 2015 - Combinando AngularJS com Java EE

Ascenção do Javascript• O debate cliente ‘leve' vs cliente ‘pesado' é antigo… • Frameworks web server-side mandaram por um tempo

(Struts, Spring, MVC, JSF) • Ajax foi uma mudança suave para o client-side (GWT,

Vaadin) • Rich clients estão voltando voltaram, graças ao

JavaScript/HTML5 • Motores Javascript melhoraram muito • Melhores ferramentas desenvolvimento • Melhores padrões (CSS3, HTML5, Websocket)

Page 6: QCon 2015 - Combinando AngularJS com Java EE

Arquitetura Rich Client

Page 7: QCon 2015 - Combinando AngularJS com Java EE

Arquitetura Rich Client• Similar a arquiteturas cliente/servidor

• Client responsável pela UI, input, validação, lógica e estado

• Server responsável pela lógica de negócio, modelo de domínio, persistência

• Web/HTTP é a cola que conecta client e server • Protocolos de comunicação comuns

• REST na maioria dos casos • WebSocket quando precisa de comunicação full-duplex • Ferramentas Javascript suportam REST muito bem, mas

ainda não WebSocket • O formato comum (talvez ideal?) de troca de dados é JSON

Page 8: QCon 2015 - Combinando AngularJS com Java EE

Arquitetura REST

Page 9: QCon 2015 - Combinando AngularJS com Java EE

Arquitetura REST• Características:

• ︎Protocolo cliente/servidor sem estado (HTTP) • ︎Operações bem definidas (GET, POST, PUT) • ︎Sintaxe universal para identificação de recursos

(URL) • ︎Transferência de informações em formato padrão

(XML, HTML, JSON)

• Web Services que seguem a arquitetura REST são denominados RESTful

Page 10: QCon 2015 - Combinando AngularJS com Java EE

RESTful Web Services

Page 11: QCon 2015 - Combinando AngularJS com Java EE

HATEOAS• Hypermedia As The Engine of Application State • Clientes somente precisam saber a URI root da aplicação e os media

types utilizados • Descrevem o estado atual da aplicação e como navegar para o

próximo estado

Page 12: QCon 2015 - Combinando AngularJS com Java EE

Java EE é uma ótima plataforma server-side para esta arquitetura

Page 13: QCon 2015 - Combinando AngularJS com Java EE

Java EE History

J2EE 1.3 CMP, Connector Architecture

J2EE 1.4 Web Services Mgmt, Deployment, Async Connector

Java EE 5 Ease of Development, EJB 3, JPA, JSF, JAXB, JAX-WS, StAX, SAAJ

Java EE 6 Pruning, Extensibility Ease of Dev, CDI, JAX-RS

Web$Profile$$Servlet 3, EJB 3.1 Lite !

Java EE 7 !JMS 2, Batch, TX, Concurrency, Interceptor, WebSocket, JSON!

Web$Profile$$JAX-RS 2 !

JAX-RPC, CMP/ BMP, JSR 88

Page 14: QCon 2015 - Combinando AngularJS com Java EE

Java EE 7

Page 15: QCon 2015 - Combinando AngularJS com Java EE

Java EE + JavaScript

EJB 3

Servlet

CDI

JPA

JAX-RS

Bean Validation

Java API for WebSocket

Java API for JSON

JMS JTA

JavaScript/HTML5

JAXB

JCA

Page 16: QCon 2015 - Combinando AngularJS com Java EE

JAX-RS• Suporte a RESTful em Java • API padronizada • Programação declarativa • Abstrações para implementação no server e client • Serviços implementados via POJO • Configuração via anotações

• @Path, @GET, @POST, @PUT, @DELETE, @PathParam, @QueryParam, @Produces, @Consumes, etc

• Plugável e extensível • Providers, filters, interceptors, validators • Suporte a processamento assíncrono • Integrado com as tecnologias do Java EE

Page 17: QCon 2015 - Combinando AngularJS com Java EE

JAX-RS@Path Define a URI para ser utilizada pelo endpoint

@GET Determina acesso ao serviço via HTTP GET

@POST Determina acesso ao serviço via HTTP POST

@PUT Determina acesso ao serviço via HTTP PUT

@DELETE Determina acesso ao serviço via HTTP DELETE

@HEAD Determina acesso ao serviço via HTTP HEAD

@PathParam Define o mapeamento do valor informado na URI para um determinado parâmetro de método

@QueryParam Define o mapeamento do valor informado na query string para um determinado parâmetro de método

@Consumes Define um determinado MIME type para recebimento de dados pelo serviço

@Produces Define um determinado MIME type para envio de dados pelo serviço

@Provider Define um determinado componente para auxiliar no JAX-RS runtime.

@ApplicationPath Determina o root path de uma aplicação JAX-RS

Page 18: QCon 2015 - Combinando AngularJS com Java EE

Manipulação de Parâmetros• Além do @PathParam há outras cinco anotações que

permitem extrair informação de um request • @QueryParam e @DefaultValue

• Extraem dados de um query string (?nome=valor&nome=valor) • @FormParam

• Extrai dados de um formulário (applicaton/x-www-form-urlencoded) • @CookieParam

• Extrai dados de cookies (pares nome=valor) • @HeaderParam

• Extrai dados de cabeçalhos HTTP • @MatrixParam

• Extrai dados de segmentos de URL

Page 19: QCon 2015 - Combinando AngularJS com Java EE

Validação de Dados• Os dados enviados para métodos em classes de resource

podem ser validados através da API Bean Validation, que é configurada via anotações

@POST@Path("/criar")@Consumes(MediaType.APPLICATION_FORM_URLENCODED)public void criarFilme( @NotNull @FormParam("titulo") String titulo, @NotNull @FormParam("diretor") String diretor, @Min(1900) @FormParam("ano") int ano) { ... }

@Pattern(regexp="tt[0-9]{5-7}")private String imdbCode;

Page 20: QCon 2015 - Combinando AngularJS com Java EE

Conversão de Dados• ParamConverterProvider pode ser utilizado para gerenciar a

conversão de objetos customizados Object para String e vice-versa • Por exemplo, pode ser utilizado para produzir um objeto java.util.Date a

partir de uma String formatada.

@Providerpublic class MyBeanConverterProvider implements ParamConverterProvider { @Override public <T> ParamConverter<T> getConverter( Class<T> clazz, Type type, Annotation[] annotations) { if (clazz.getName().equals(MyBean.class.getName())) { return new ParamConverter<T>() { @Override public T fromString(String value) {...} @Override public String toString(T bean) {...} }; } return null; }}

Page 21: QCon 2015 - Combinando AngularJS com Java EE

Tratamento de Exceções• Geração e lançamento da exceção customizada

• Exemplo de definição de exceção customizadapublic class CustomNotFoundException extends WebApplicationException { public CustomNotFoundException() { super(Responses.notFound().build()); } }

@Path("items/{itemid}/")public Item getItem(@PathParam("itemid") String itemid) { Item i = getItems().get(itemid); if (i == null) { throw new CustomNotFoundException("Item, " + itemid + ", is not found"); } return i;}

Page 22: QCon 2015 - Combinando AngularJS com Java EE

Filtros e Interceptadores

Page 23: QCon 2015 - Combinando AngularJS com Java EE

Filtros• Filtros podem ser server side e/ou client side

• ContainerRequestFilter, ContainerResponseFilter • ClientRequestFilter, ClientResponseFilter

public class AuthorizationRequestFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext)

throws IOException { final SecurityContext securityContext = requestContext.getSecurityContext(); if (securityContext == null || !securityContext.isUserInRole("privileged")) { requestContext.abortWith(Response.status( Response.Status.UNAUTHORIZED) .entity("User cannot access the resource.").build()); } }}

Page 24: QCon 2015 - Combinando AngularJS com Java EE

Interceptadores• Existem dois tipos de interceptors (Reader e Writer)

// @Compress annotation is the name binding annotation@NameBinding@Retention(RetentionPolicy.RUNTIME)public @interface Compress {}

@Path("helloworld")public class HelloWorldResource { @GET @Path("too-much-data") @Compress public String getVeryLongString() {...}}

@Compresspublic class GZIPWriterInterceptor implements WriterInterceptor { @Override public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {...}}

Page 25: QCon 2015 - Combinando AngularJS com Java EE

@Context• @Context pode ser utilizado para injetar diversos objetos

contextuais disponíveis em uma requisição ou resposta HTTP • Objetos da Servlet API

• ServletConfig

• ServletContext

• HttpServletRequest

• HttpServletResponse

• Objetos da JAX-RS API • Application

• UriInfo

• Request

• HttpHeaders

• SecurityContext

• Providers

@ContextRequest request;@ContextUriInfo uriInfo;

@PUTpublic metodo(@Context HttpHeaders headers) { String m = request.getMethod(); URI ap = uriInfo.getAbsolutePath(); Map<String, Cookie> c = headers.getCookies();}

@GET @Path("auth")public login(@Context SecurityContext sc) { String userid = sc.getUserPrincipal().getName(); if (sc.isUserInRole("admin")) { ... } }

Page 26: QCon 2015 - Combinando AngularJS com Java EE

Hypermedia Support• JAX-RS oferece um modelo para suportar HATEOAS por

meio de suporte à hypermedia • Em cada mensagem de resposta, deve ser incluído os links

para a próxima mensagem • Utilizando este suporte, a aplicação consegue definir todo o

modelo de navegação via HTTP@POST@Consumes({"application/json", "application/xml"})@Produces({"application/json", "application/xml"})public Response create(Article article) {

Article created = articleDao.create(article);return Response.ok(created)

.link("link-URI", "link-rel") .links(produceLinks(created)) .build();

}

private Link[] produceLinks(Article article) {...}

Page 27: QCon 2015 - Combinando AngularJS com Java EE

Integração com CDI• JAX-RS integra-se muito bem com as tecnologias da

plataforma Java Enterprise, especialmente com os componentes EJBs e CDI.

• CDI beans podem ser injetados diretamente nos resources. Providers e Application terão comportamento singleton ou @ApplicationScoped

@Path("/cdibean")public class CdiBeanResource { @Inject MyOtherCdiBean bean; // CDI injected bean @GET @Produces("text/plain") public String getIt() { return bean.getIt(); }}

Page 28: QCon 2015 - Combinando AngularJS com Java EE

Integração com EJB• Exemplo de integração com EJB

@Localpublic interface LocalEjb { @GET @Produces("text/plain") public String getIt();} @Stateless@Path("/stateless")public class StatelessEjbResource implements LocalEjb { @Override public String getIt() { return "Hi Stateless!"; }}

Page 29: QCon 2015 - Combinando AngularJS com Java EE

Cache Control• JAX-RS suporta configurações para controle de caching de

responses HTTP por meio da classe CacheControl

@GET@Path("{id}")public Response read(@PathParam("id") int id) { Article article = articleDao.findById(id); CacheControl cacheControl = new CacheControl(); cacheControl.setMaxAge(60); return Response.ok(article) .cacheControl(cacheControl) .build();}

Page 30: QCon 2015 - Combinando AngularJS com Java EE

Chamadas Assíncronas• Possibilita o processamento multithread no servidor,

aumentando o seu throughput • Libera a thread do servidor para executar outras tarefas • @Suspended indica que o método será executado de

maneira assíncrona • Possível configurar timeout@Path(“Async") @RequestScopepublic class AsyncResource { @GET public void asyncGet(@Suspended final AsyncResponse asyncResponse) { new Thread(new Runnable() {...}).start(); } }

Page 31: QCon 2015 - Combinando AngularJS com Java EE

WebSocket• Oferece comunicação bi-direcional (full-duplex) através

de uma simples conexão TCP • Inicia através de um hand-shake através do protocolo

HTTP, mas as conversações utilizam o protocolo WebSockets.

• Suporte requisições assíncronas • Perfeito para aplicações como chat e jogos • Utiliza as tecnologias web existentes

Page 32: QCon 2015 - Combinando AngularJS com Java EE

WebSocket

Server Client

Connected !

open open

close

message

message

error

message message

Disconnected

Page 33: QCon 2015 - Combinando AngularJS com Java EE

WebSocket

Web

Soc

ket

End

poin

t

Client

Client

Client

Remote Endpoint

Remote Endpoint

Remote Endpoint

Session

Message Handler

Session

Message Handler

Session

Message Handler

Internet

Page 34: QCon 2015 - Combinando AngularJS com Java EE

REST vs. WebSocket

Page 35: QCon 2015 - Combinando AngularJS com Java EE

Java API for WebSocket• Programação declarativa com anotações • Client and server-side • Powerful API

• @ServerEndpoint, @OnOpen, @OnClose, @OnMessage, @OnError, Session, Remote

• Plugável e extensível • Encoders, decoders, sub-protocols

• Lifecycle callback handlers • Permite empacotá-los em aplicações Java EE

Page 36: QCon 2015 - Combinando AngularJS com Java EE

Java API for WebSocket• Define o endpoint do servidor WebSocket para

conexão pelos clientes

@ServerEndpoint(”/chat”)public class ChatServer { @OnOpen public void onOpen(Session peer) {...} @OnClose public void onClose(Session peer) { ... } @OnMessage public void message(String message, Session client) throws IOException {...} @OnError public void error(Session session, Throwable t) { ... }}

Page 37: QCon 2015 - Combinando AngularJS com Java EE

Java API for WebSocket• Exemplo de cliente em JavaScript

var wsUri = "ws://" + document.location.hostname + ":" + document.location.port + document.location.pathname + "chat";

var websocket = new WebSocket(wsUri);websocket.onopen = function(evt) { onOpen(evt) };websocket.onmessage = function(evt) { onMessage(evt) };websocket.onerror = function(evt) { onError(evt) };

Page 38: QCon 2015 - Combinando AngularJS com Java EE

JSON• JavaScript Object Notation

• Pode ser codificado diretamente em String e processado com métodos como split(), substring(), indexOf() dentre outros

• Java EE 7 disponibiliza um API para construir objetos JSON e para converter strings JSON em mapas • É um par de APIs de baixo nível (não é mapeamento objeto-

JSON) • Existem várias implementações que fazem mapeamento (binding)

objeto-JSON automático (não são parte do Java EE) • MOXy, Jettison, Jersey, Jackson, etc.

{id:123, cidade:”Paris”, voos:[“M344”,”J919”]}

Page 39: QCon 2015 - Combinando AngularJS com Java EE

Java API for JSON• API para parser e geração de objetos JSON definida

pelo Java EE • Object Model API - javax.json

• Análogo a DOM: estrutura em árvore; I/O streaming via decorators

• JsonObject: representa um objeto JSON • JsonArray: representa um array JSON • Leitura e gravação usando JsonReader e JsonWriter

• JSON Streaming API - javax.json.stream • Análogo a SAX: leitura sequencial (baixo nível) • JsonParser: permite ler um stream JSON e capturar eventos • JsonGenerator: métodos para criar uma estrutura JSON

Page 40: QCon 2015 - Combinando AngularJS com Java EE

Java API for JSON• JSON Object Model API

[

{

"type": "home”, "number": "212 555-1234"

},

{

"type": "fax”, "number": "646 555-4567"

}

]

JsonArray value =

Json.createArrayBuilder()

.add(Json.createObjectBuilder()

.add("type", "home")

.add("number", "212 555-1234")

)

.add(Json.createObjectBuilder()

.add("type", "fax")

.add("number", "646 555-4567")

)

.build();

Page 41: QCon 2015 - Combinando AngularJS com Java EE

Java API for JSON• JSON Streaming{

"firstName": "John", "lastName": "Smith", "age": 25,

"phoneNumber": [

{ "type": "home", "number": "212 555-1234" },

{ "type": "fax", "number": "646 555-4567" }

]

}

Event event = parser.next(); // START_OBJECT

event = parser.next(); // KEY_NAME

event = parser.next(); // VALUE_STRING

String name = parser.getString(); // "John�

Page 42: QCon 2015 - Combinando AngularJS com Java EE

JAXB• JAXB beans permitem reutilizar o mesmo JavaBean

para gerar representações JSON e XML no response

@XmlRootElementpublic class MyJaxbBean { public String name; public int age; ...}

@GET@Produces("application/json")public MyJaxbBean getMyBean() { return new MyJaxbBean("Agamemnon", 32);}

{"name":"Agamemnon",  "age":"32"}

Page 43: QCon 2015 - Combinando AngularJS com Java EE

AngularJS é uma ótima alternativa para implementação Web rich client

Page 44: QCon 2015 - Combinando AngularJS com Java EE

AngularJS• Framework JavaScript MVW* client-side para

desenvolver aplicações web modernas e dinâmicas • A primeira versão open-source foi liberada em 2010 e

desde então ele é mantido pela Google e pela comunidade

• Aproximadamente 2 releases mensais, projeto altamente ativo

• O que faz o AngularJS ser especial?

Page 45: QCon 2015 - Combinando AngularJS com Java EE

AngularJS• Google Trends

Page 46: QCon 2015 - Combinando AngularJS com Java EE

AngularJS• Jobs Trends

dice.com

indeed.com

Page 47: QCon 2015 - Combinando AngularJS com Java EE

AngularJS• Diferenciais

• Organização da bagunça no client-side • Views, modules, controllers, services, providers, etc

• Reutilização de código e modularidade (DRY) • Killer Features

• Two-way data binding • Dependency Injection • Controllers, Services • Directives, Filters, Templates, etc

• Integração natural com REST, SOA, SOFEA • Ótima testabilidade

Page 48: QCon 2015 - Combinando AngularJS com Java EE

AngularJS• Two-way data binding

Page 49: QCon 2015 - Combinando AngularJS com Java EE

AngularJS• Dependency Injection

.controller('LoginController', function($scope, $rootScope, $location, $http, $cookieStore, LoginService) { $scope.login = function () { LoginService.authenticate($.param({username: $scope.username, password: $scope.password}), function (user) { $rootScope.user = user; $http.defaults.headers.common[xauth] = user.token; $cookieStore.put('user', user); $location.path("/"); }); };})

Page 50: QCon 2015 - Combinando AngularJS com Java EE

AngularJS• Controllers

var myApp = angular.module('myApp',[]);

myApp.controller('GreetingController', ['$scope', function($scope) { $scope.greeting = "Hola!";}]);

<div ng-controller="GreetingController"> {{ greeting }}</div>

Page 51: QCon 2015 - Combinando AngularJS com Java EE

AngularJS

var services = angular.module( "myApp.services", ["ngResource"]); services.factory("LoginService", function($resource) { return $resource(":action", {}, { authenticate: { method: "POST", params: {"action": "authenticate"}, headers: {“Content-Type": "application/json"}} } );});

• Services

Page 52: QCon 2015 - Combinando AngularJS com Java EE

JavaScript Tools

Page 53: QCon 2015 - Combinando AngularJS com Java EE

Demo• Java EE + AngularJS

• https://github.com/rcandidosilva/javaee-javascript

Page 54: QCon 2015 - Combinando AngularJS com Java EE

Conclusões…• Clientes Javascript/HTML5 estão conquistando

desenvolvedores • Comunicação entre cliente e servidor em JSON via REST

ou WebSocket • Java EE funciona muito bem como backend para clientes

ricos em Javascript, especialmente JAX-RS, Java API para WebSockets, e JSON-P

• Enjoy it ;)

Page 55: QCon 2015 - Combinando AngularJS com Java EE

Perguntas

?

Page 56: QCon 2015 - Combinando AngularJS com Java EE

Referências• http://docs.oracle.com/javaee/7/tutorial/ • https://en.wikipedia.org/wiki/Representational_state_transfer • https://jax-rs-spec.java.net • http://www.radcortez.com/java-ee-7-with-angular-js-part-1/ • https://docs.angularjs.org/guide/ • http://www.slideshare.net/reza_rahman/javaee-javascript • http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/HomeWebsocket/

WebsocketHome.html • http://jhipster.github.io/ • http://yeoman.io/ • http://gruntjs.com/ • http://bower.io/ • http://requirejs.org/ • http://karma-runner.github.io/0.13/index.html • http://jshint.com/ • https://www.npmjs.com/ • https://jquery.com/ • http://gulpjs.com/

Page 57: QCon 2015 - Combinando AngularJS com Java EE

Muito obrigado! @rcandidosilva

rodrigocandido.me