Date post: | 13-Apr-2017 |
Category: |
Software |
Upload: | rodrigo-candido-da-silva |
View: | 1,317 times |
Download: | 2 times |
Combinando AngularJS com Java EERodrigo Cândido da Silva @rcandidosilva
About Me• Software Architect
• http://integritastech.com • JUG Leader do GUJavaSC
• http://gujavasc.org • Twitter
• @rcandidosilva • Contatos
• http://rodrigocandido.me
Agenda• Arquitetura Rich Client • RESTful Web Services • Java EE 7
• JAX-RS • WebSocket • JSON-P
• AngularJS • Demo
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
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)
Arquitetura Rich Client
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
Arquitetura REST
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
RESTful Web Services
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
Java EE é uma ótima plataforma server-side para esta arquitetura
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
Java EE 7
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
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
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
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
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;
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; }}
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;}
Filtros e Interceptadores
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()); } }}
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 {...}}
@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")) { ... } }
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) {...}
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(); }}
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!"; }}
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();}
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(); } }
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
WebSocket
Server Client
Connected !
open open
close
message
message
error
message message
Disconnected
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
REST vs. WebSocket
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
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) { ... }}
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) };
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”]}
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
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();
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�
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"}
AngularJS é uma ótima alternativa para implementação Web rich client
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?
AngularJS• Google Trends
AngularJS• Jobs Trends
dice.com
indeed.com
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
AngularJS• Two-way data binding
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("/"); }); };})
AngularJS• Controllers
var myApp = angular.module('myApp',[]);
myApp.controller('GreetingController', ['$scope', function($scope) { $scope.greeting = "Hola!";}]);
<div ng-controller="GreetingController"> {{ greeting }}</div>
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
JavaScript Tools
Demo• Java EE + AngularJS
• https://github.com/rcandidosilva/javaee-javascript
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 ;)
Perguntas
?
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/
Muito obrigado! @rcandidosilva
rodrigocandido.me