Você está na página 1de 56

Combinando AngularJS com Java EE

Rodrigo Cndido 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 dinmico
Mais stateless
Maior escalabilidade

Asceno 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 mudana suave para o client-side (GWT,
Vaadin)
Rich clients esto voltando voltaram, graas ao
JavaScript/HTML5
Motores Javascript melhoraram muito
Melhores ferramentas desenvolvimento
Melhores padres (CSS3, HTML5, Websocket)

Arquitetura Rich Client

Arquitetura Rich Client


Similar a arquiteturas cliente/servidor
Client responsvel pela UI, input, validao, lgica e

estado
Server responsvel pela lgica de negcio, modelo de
domnio, persistncia
Web/HTTP a cola que conecta client e server
Protocolos de comunicao comuns
REST na maioria dos casos
WebSocket quando precisa de comunicao full-duplex
Ferramentas Javascript suportam REST muito bem, mas
ainda no WebSocket
O formato comum (talvez ideal?) de troca de dados JSON

Arquitetura REST

Arquitetura REST
Caractersticas:
Protocolo cliente/servidor sem estado (HTTP)
Operaes bem definidas (GET, POST, PUT)
Sintaxe universal para identificao de recursos

(URL)
Transferncia de informaes em formato padro
(XML, HTML, JSON)
Web Services que seguem a arquitetura REST so

denominados RESTful

RESTful Web Services

HATEOAS
Hypermedia As The Engine of Application State
Clientes somente precisam saber a URI root da aplicao e os media

types utilizados
Descrevem o estado atual da aplicao e como navegar para o
prximo estado

Java EE uma tima plataforma


server-side para esta arquitetura

Java EE History
Java EE 7
!

Java EE 6
Java EE 5

J2EE 1.4
J2EE 1.3
CMP,
Connector
Architecture

Web
Services
Mgmt,
Deployment,
Async
Connector

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

Pruning,
Extensibility
Ease of Dev,
CDI, JAX-RS

JMS 2,
Batch, TX,
Concurrency,
Interceptor,
WebSocket,
JSON!

JAX-RPC, CMP/
BMP, JSR 88

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

Web$Prole$
$
JAX-RS 2
!

Java EE 7

Java EE + JavaScript
JavaScript/HTML5

Java API for


WebSocket

JAX-RS

Java API for


JSON

JAXB
Bean Validation

Servlet

EJB 3

JPA

CDI

JMS

JTA

JCA

JAX-RS
Suporte a RESTful em Java
API padronizada
Programao declarativa
Abstraes para implementao no server e client
Servios implementados via POJO
Configurao via anotaes
@Path, @GET, @POST, @PUT, @DELETE, @PathParam,

@QueryParam, @Produces, @Consumes, etc

Plugvel e extensvel
Providers, filters, interceptors, validators
Suporte a processamento assncrono
Integrado com as tecnologias do Java EE

JAX-RS
@Path

Define a URI para ser utilizada pelo endpoint

@GET

Determina acesso ao servio via HTTP GET

@POST

Determina acesso ao servio via HTTP POST

@PUT

Determina acesso ao servio via HTTP PUT

@DELETE

Determina acesso ao servio via HTTP DELETE

@HEAD

Determina acesso ao servio via HTTP HEAD

@PathParam

Define o mapeamento do valor informado na URI para um


determinado parmetro de mtodo

@QueryParam

Define o mapeamento do valor informado na query string


para um determinado parmetro de mtodo

@Consumes

Define um determinado MIME type para recebimento de


dados pelo servio

@Produces

Define um determinado MIME type para envio de dados


pelo servio

@Provider

Define um determinado componente para auxiliar no JAXRS runtime.

@ApplicationPath

Determina o root path de uma aplicao JAX-RS

Manipulao de Parmetros
Alm do @PathParam h outras cinco anotaes que

permitem extrair informao de um request


@QueryParam e @DefaultValue
Extraem dados de um query string (?nome=valor&nome=valor)

@FormParam
Extrai dados de um formulrio (applicaton/x-www-form-urlencoded)
@CookieParam
Extrai dados de cookies (pares nome=valor)
@HeaderParam
Extrai dados de cabealhos HTTP
@MatrixParam
Extrai dados de segmentos de URL

Validao de Dados
Os dados enviados para mtodos em classes de resource

podem ser validados atravs da API Bean Validation, que


configurada via anotaes
@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;

Converso de Dados
ParamConverterProvider pode ser utilizado para gerenciar a

converso 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 <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 Excees
Gerao e lanamento da exceo customizada
@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;
}

Exemplo de definio de exceo customizada


public class CustomNotFoundException extends WebApplicationException {
public CustomNotFoundException() {
super(Responses.notFound().build());
}
}

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

@Context
@Context pode ser utilizado para injetar diversos objetos

contextuais disponveis em uma requisio 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<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 includo os links
para a prxima mensagem
Utilizando este suporte, a aplicao consegue definir todo o
modelo de navegao 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) {...}

Integrao 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 tero comportamento
singleton ou @ApplicationScoped
@Path("/cdibean")
public class CdiBeanResource {
@Inject MyOtherCdiBean bean;
@GET
@Produces("text/plain")
public String getIt() {
return bean.getIt();
}
}

// CDI injected bean

Integrao com EJB


Exemplo de integrao 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!";
}
}

Cache Control
JAX-RS suporta configuraes 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 Assncronas
Possibilita o processamento multithread no servidor,

aumentando o seu throughput


Libera a thread do servidor para executar outras tarefas
@Suspended indica que o mtodo ser executado de
maneira assncrona
Possvel configurar timeout
@Path(Async") @RequestScope
public class AsyncResource {
@GET
public void asyncGet(@Suspended final AsyncResponse asyncResponse) {
new Thread(new Runnable() {...}).start();
}
}

WebSocket
Oferece comunicao bi-direcional (full-duplex) atravs

de uma simples conexo TCP


Inicia atravs de um hand-shake atravs do protocolo
HTTP, mas as conversaes utilizam o protocolo
WebSockets.
Suporte requisies assncronas
Perfeito para aplicaes como chat e jogos
Utiliza as tecnologias web existentes

WebSocket
Connected !

open

open

message

Client

message

error
message

Server
message

close

Disconnected

WebSocket

Client

Remote
Endpoint

Session

Message
Handler

Remote
Endpoint

Internet

Session

Message
Handler

Client

Remote
Endpoint

Session

WebSocket
Endpoint

Client

Message
Handler

REST vs. WebSocket

Java API for WebSocket


Programao declarativa com anotaes
Client and server-side
Powerful API
@ServerEndpoint, @OnOpen, @OnClose, @OnMessage,
@OnError, Session, Remote
Plugvel e extensvel
Encoders, decoders, sub-protocols
Lifecycle callback handlers
Permite empacot-los em aplicaes Java EE

Java API for WebSocket


Define o endpoint do servidor WebSocket para

conexo 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
{id:123, cidade:Paris, voos:[M344,J919]}

Pode ser codificado diretamente em String e processado com

mtodos 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 nvel (no mapeamento objeto-

JSON)
Existem vrias implementaes que fazem mapeamento (binding)
objeto-JSON automtico (no so parte do Java EE)
MOXy, Jettison, Jersey, Jackson, etc.

Java API for JSON


API para parser e gerao de objetos JSON definida

pelo Java EE
Object Model API - javax.json
Anlogo a DOM: estrutura em rvore; I/O streaming via

decorators
JsonObject: representa um objeto JSON
JsonArray: representa um array JSON
Leitura e gravao usando JsonReader e JsonWriter
JSON Streaming API - javax.json.stream
Anlogo a SAX: leitura sequencial (baixo nvel)
JsonParser: permite ler um stream JSON e capturar eventos
JsonGenerator: mtodos para criar uma estrutura JSON

Java API for JSON


JSON Object Model API
JsonArray value =
Json.createArrayBuilder()

[
{

.add(Json.createObjectBuilder()
.add("type", "home")

"type": "home ,

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

"number": "212 555-1234"

},

.add(Json.createObjectBuilder()

.add("type", "fax")

"type": "fax ,

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

"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 representaes 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"}

AngularJS uma tima alternativa para


implementao Web rich client

AngularJS
Framework JavaScript MVW* client-side para

desenvolver aplicaes web modernas e dinmicas


A primeira verso open-source foi liberada em 2010 e
desde ento 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

indeed.com

dice.com

AngularJS
Diferenciais
Organizao da baguna no client-side
Views, modules, controllers, services, providers, etc
Reutilizao de cdigo e modularidade (DRY)
Killer Features
Two-way data binding
Dependency Injection
Controllers, Services
Directives, Filters, Templates, etc
Integrao 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
Services
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"}}
}
);
});

JavaScript Tools

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

Concluses
Clientes Javascript/HTML5 esto conquistando

desenvolvedores
Comunicao 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

Muito obrigado!
@rcandidosilva
rodrigocandido.me

Você também pode gostar