Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

About Me • Software Architect • http://integritastech.com • JUG Leader do GUJavaSC • http://gujavasc.org • Twitter • @rcandidosilva • Contatos • http://rodrigocandido.me

Slide 3

Slide 3 text

Agenda • Arquitetura Rich Client • RESTful Web Services • Java EE 7 • JAX-RS • WebSocket • JSON-P • AngularJS • Demo

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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)

Slide 6

Slide 6 text

Arquitetura Rich Client

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

Arquitetura REST

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

RESTful Web Services

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Java EE 7

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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;

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Tratamento de Exceções • Geração e lançamento da exceção customizada • Exemplo de definição de exceção customizada public 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; }

Slide 22

Slide 22 text

Filtros e Interceptadores

Slide 23

Slide 23 text

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()); } } }

Slide 24

Slide 24 text

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() {...} } @Compress public class GZIPWriterInterceptor implements WriterInterceptor { @Override public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {...} }

Slide 25

Slide 25 text

@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 @Context Request request; @Context UriInfo uriInfo; @PUT public metodo(@Context HttpHeaders headers) { String m = request.getMethod(); URI ap = uriInfo.getAbsolutePath(); Map c = headers.getCookies(); } @GET @Path("auth") public login(@Context SecurityContext sc) { String userid = sc.getUserPrincipal().getName(); if (sc.isUserInRole("admin")) { ... } }

Slide 26

Slide 26 text

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) {...}

Slide 27

Slide 27 text

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(); } }

Slide 28

Slide 28 text

Integração com EJB • Exemplo de integração com EJB @Local public interface LocalEjb { @GET @Produces("text/plain") public String getIt(); } @Stateless @Path("/stateless") public class StatelessEjbResource implements LocalEjb { @Override public String getIt() { return "Hi Stateless!"; } }

Slide 29

Slide 29 text

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(); }

Slide 30

Slide 30 text

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") @RequestScope public class AsyncResource { @GET public void asyncGet(@Suspended final AsyncResponse asyncResponse) { new Thread(new Runnable() {...}).start(); } }

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

WebSocket Server Client Connected ! open open close message message error message message Disconnected

Slide 33

Slide 33 text

WebSocket WebSocket Endpoint Client Client Client Remote Endpoint Remote Endpoint Remote Endpoint Session Message Handler Session Message Handler Session Message Handler Internet

Slide 34

Slide 34 text

REST vs. WebSocket

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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) { ... } }

Slide 37

Slide 37 text

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) };

Slide 38

Slide 38 text

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”]}

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

Java API for JSON • JSON Object Model API [ { "type": "homez, "number": "212 555-1234" }, { "type": "faxz, "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();

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

JAXB • JAXB beans permitem reutilizar o mesmo JavaBean para gerar representações JSON e XML no response @XmlRootElement public class MyJaxbBean { public String name; public int age; ... } @GET @Produces("application/json") public MyJaxbBean getMyBean() { return new MyJaxbBean("Agamemnon", 32); } {"name":"Agamemnon", "age":"32"}

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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?

Slide 45

Slide 45 text

AngularJS • Google Trends

Slide 46

Slide 46 text

AngularJS • Jobs Trends dice.com indeed.com

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

AngularJS • Two-way data binding

Slide 49

Slide 49 text

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("/"); }); }; })

Slide 50

Slide 50 text

AngularJS • Controllers var myApp = angular.module('myApp',[]); myApp.controller('GreetingController', ['$scope', function($scope) { $scope.greeting = "Hola!"; }]);
{{ greeting }}

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

JavaScript Tools

Slide 53

Slide 53 text

Demo • Java EE + AngularJS • https://github.com/rcandidosilva/javaee-javascript

Slide 54

Slide 54 text

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 ;)

Slide 55

Slide 55 text

Perguntas ?

Slide 56

Slide 56 text

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/

Slide 57

Slide 57 text

Muito obrigado! @rcandidosilva rodrigocandido.me