Novas APIs do
Java EE 7
E a batalha contra a complexidade
Helder da Rocha
helder@argonavis.com.br
Objetivos
Falar um pouco de complexidade do software e
apresentar três APIs do Java EE 7 que simplificam o
processo de desenvolvimento
Conteúdo
Breve reflexão sobre complexidade e entropia
JMS 2.0
APIs de Web Services (SOAP e REST)
O futuro?
2
"A complexidade do
software é uma
propriedade 

essencial, e não
acidental"
F. Brooks
Ilusão da simplicidade
Fonte: Booch
Fonte: Grady Booch "Object Oriented Analysis and Design"
Evolução das APIs
Uma API deve ser a mais simples possível
Contratos mais simples
Menos burocracia
Menos necessidade de documentação
Mas… problema inerente ao software: complexidade
Entropia sempre crescente
Sucesso depende do controle da complexidade
6
1.0
2.0
3.0
1.0
1.0
2.0
Java EE 7
Objetivo sempre presente na evolução das APIs:
Simplificar o uso!
Menor curva de aprendizado
Mais defaults, menos configuração
Menos, menos, menos
(até mesmo o JSF conseguiu ficar mais simples na Java EE 7 :-)
Java Message Service 1.0
Queue

Connection

Factory
Queue

Connection
Queue

Session
Queue

Sender
Queue

Receiver
Message
Queue
createSession()
jndi.lookup(queueFactory)
createConnection()
createMessage()
create() create()
receive()send()
jndi.lookup(queue)
API para enviar e receber
mensagens usa classes e
métodos diferentes para
domínios Queue e Topic
Java Message Service 1.1
Connection

Factory
Connection
SessionMessage

Producer
Message

Consumer
Message
Destination
createSession()
jndi.lookup(factory)
createConnection()
createMessage()
create() create()
receive()send()
jndi.lookup(destination)
API para enviar e receber
mensagens usa classes e
métodos iguais para
domínios Queue e Topic
Java Message Service 2.0
10
Connection

Factory
JMSContextJMSProducer JMSConsumer
Message
Destination
@Inject factory
createJMSContext()
createMessage()
create() create()
receive()send()
@Inject destination
@Inject em vez de JNDI
Menos código para enviar
e receber mensagens
Java Message Service 2.0
11
Connection

Factory
JMSContext
Destination
@Inject factory
createJMSContext()
receive()send()
@Inject destination
Menos código!
Menos código!
Envio de mensagens JMS 2.0
Antes (JMS 1.1)
JMS 2.0
12
public	
  void	
  sendJMS2(ConnectionFactory	
  conFactory,	
  Queue	
  queue,	
  String	
  text)	
  {	
  
	
  	
  	
  try	
  (JMSContext	
  context	
  =	
  conFactory.createContext();)	
  {	
  
	
  	
  	
  	
  	
  	
  context.createProducer().send(queue,	
  text);	
  
	
  	
  	
  }	
  catch	
  (JMSRuntimeException	
  ex)	
  {	
  //	
  handle	
  exception	
  }	
  
}
public	
  void	
  sendJMS11(ConnectionFactory	
  conFactory,	
  Queue	
  queue,	
  String	
  text)	
  {	
  
	
  	
  	
  try	
  {	
  

	
  	
  	
  	
  	
  	
  Connection	
  con	
  =	
  conFactory.createConnection();	
  

	
  	
  	
  	
  	
  	
  try	
  {	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  Session	
  session	
  =	
  con.createSession(false,Session.AUTO_ACKNOWLEDGE);	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  MessageProducer	
  messageProducer	
  =	
  session.createProducer(queue);	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  TextMessage	
  textMessage	
  =	
  session.createTextMessage(text);	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  messageProducer.send(textMessage);	
  

	
  	
  	
  	
  	
  	
  }	
  finally	
  {	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  connection.close();	
  

	
  	
  	
  	
  	
  	
  }	
  

	
  	
  	
  }	
  catch	
  (JMSException	
  ex)	
  {	
  //	
  handle	
  exception	
  }	
  
	
  }
Recebimento síncrono JMS 2.0
13
Antes (JMS 1.1)
JMS 2.0
public	
  void	
  recJMS2(ConnectionFactory	
  conFactory,	
  Queue	
  queue,	
  String	
  text)	
  {	
  
	
  	
  	
  try	
  (JMSContext	
  context	
  =	
  conFactory.createContext();){	
  
	
  	
  	
  	
  	
  	
  JMSConsumer	
  consumer	
  =	
  context.createConsumer(queue);	
  

	
  	
  	
  	
  	
  	
  this.messageContents	
  =	
  consumer.receiveBody(String.class);

	
  	
  	
  }	
  catch	
  (JMSRuntimeException	
  ex)	
  {	
  //	
  handle	
  exception	
  }	
  
}
public	
  void	
  recJMS11(ConnectionFactory	
  conFactory,	
  Queue	
  queue,	
  String	
  text)	
  {	
  
	
  	
  	
  try	
  {	
  

	
  	
  	
  	
  	
  	
  Connection	
  con	
  =	
  conFactory.createConnection();	
  

	
  	
  	
  	
  	
  	
  try	
  {	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  Session	
  session	
  =	
  con.createSession(false,Session.AUTO_ACKNOWLEDGE);	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  MessageConsumer	
  messageConsumer	
  =	
  session.createConsumer(queue);	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  con.start();	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  TextMessage	
  textMessage	
  =	
  (TextMessage)messageConsumer.receive();	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  this.messageContents	
  =	
  textMessage.getText();

	
  	
  	
  	
  	
  	
  }	
  finally	
  {	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  connection.close();	
  

	
  	
  	
  	
  	
  	
  }	
  

	
  	
  	
  }	
  catch	
  (JMSException	
  ex)	
  {	
  //	
  handle	
  exception	
  }	
  
}
Pré-história do SOAP, parte 1

No princípio, Web Service eram simples
de codificar em XML
POST /ISBNService.jsp HTTP/1.0
Content-type: text/xml

Content-length: 90
<chamada>

<funcao>
<nome>getPrice</nome>
<param>2877142566</param>
</funcao>
</chamada>
HTTP/1.1 200 OK
Content-type: text/xml

Content-length: 77
<resposta>

<funcao>
<param>19.50</param>
</funcao>
</resposta>
ISBNService.jsp
ISBNClient
ISBNQuery
getPrice()
2877142566
19.50
BD
1
2
3
4
gera
requisição
gera
resposta
14
Pré-história do SOAP parte 2
XML-RPC: padronização dos tags para operações,
parâmetros, tipos, etc.
Criado no grupo de discussões xml-dev em 1998
<methodCall>

<methodName>getPrice</methodName>

<params>
<param>
<value><string>2877142566</string></value>
</param>
</param>
</methodCall> <methodResponse>

<params>
<param>
<value><double>19.5</double></value>
</param>
</param>
</methodResponse>
Resposta
Requisição
15
“Simples” requisição SOAP-RPC
POST /xmlrpc-bookstore/bookpoint/BookstoreIF HTTP/1.0
Content-Type: text/xml; charset="utf-8"
Content-Length: 585
SOAPAction: ""
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope
xmlns:env="http://www.w3.org/2001/12/soap-envelope"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:enc="http://www.w3.org/2001/12/soap-encoding/"
env:encodingStyle="http://www.w3.org/2001/12/soap-encoding/">
<env:Body>
<ans1:getPrice xmlns:ans1="http://mybooks.org/wsdl">
<String_1 xsi:type="xsd:string">2877142566</String_1>
</ans1:getPrice>
</env:Body>
</env:Envelope> Parâmetro (ISBN)
Payload
Mensagem
(envelope)
SOAP
16
Padronização oficial
Muito mais burocrática
Resposta SOAP-RPC
HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
SOAPAction: ""
Date: Thu, 08 Aug 2002 01:48:22 GMT
Server: Apache Coyote HTTP/1.1 Connector [1.0]
Connection: close
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope 

xmlns:env="http://www.w3.org/2001/12/soap-envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:enc="http://www.w3.org/2001/12/soap-encoding/"
xmlns:ns0="http://mybooks.org/types"
env:encodingStyle="http://www.w3.org/2001/12/soap-encoding/">
<env:Body>
<ans1:getPriceResponse xmlns:ans1="http://mybooks.org/wsdl">
<result xsi:type="xsd:decimal">19.50</result>
</ans1:getPriceResponse>
</env:Body>
</env:Envelope> Resposta (Preço)
Payload
Mensagem
(envelope)
SOAP
17
WSDL para descrever o serviço
Compare	
  com	
  a	
  
mensagem	
  SOAP	
  
mostrada	
  
anteriormente
Informa	
  onde	
  está	
  o	
  serviço	
  (endpoint)
<?xml	
  version="1.0"	
  encoding="UTF-­‐8"?>	
  
<definitions	
  name="BookstoreService"	
  

	
  	
  	
  	
  targetNamespace="http://mybooks.org/wsdl"	
  
	
  	
  	
  	
  xmlns:tns="http://mybooks.org/wsdl"	
  
	
  	
  	
  	
  xmlns="http://schemas.xmlsoap.org/wsdl/"	
  
	
  	
  	
  	
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"	
  
	
  	
  	
  	
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">	
  	
  
	
  	
  	
  <types>...</types>	
  
	
  	
  	
  <message	
  name="BookstoreIF_getPrice">	
  
	
  	
  	
  	
  	
  	
  <part	
  name="String_1"	
  type="xsd:string"/>	
  
	
  	
  	
  </message>	
  
	
  	
  	
  <message	
  name="BookstoreIF_getPriceResponse">	
  
	
  	
  	
  	
  	
  	
  <part	
  name="result"	
  type="xsd:decimal"/>	
  
	
  	
  	
  </message>	
  
	
  	
  	
  <portType	
  name="BookstoreIF">	
  	
  
	
  	
  	
  	
  	
  	
  <operation	
  name="getPrice"	
  parameterOrder="String_1">	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  <input	
  message="tns:BookstoreIF_getPrice"/>	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  <output	
  message="tns:BookstoreIF_getPriceResponse"/>	
  	
  
	
  	
  	
  	
  	
  	
  </operation>	
  
	
  	
  	
  </portType>	
  	
  
	
  	
  	
  <binding	
  ...	
  >	
  ...</binding>	
  	
  
	
  	
  	
  <service	
  ...	
  >	
  ...	
  </service>	
  	
  
</definitions>	
  
Simplificação com JAX-WS

(escondendo a complexidade do XML)
19
@WebService	
  
public	
  class	
  FilmeFacade	
  {	
  
	
  	
  	
  	
  @PersistenceContext(unitName	
  =	
  "FilmesServiceSoap")	
  
	
  	
  	
  	
  EntityManager	
  em;	
  
	
  	
  	
  	
  	
  
	
  	
  	
  	
  public	
  List<Filme>	
  getFilmes()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  String	
  jpql	
  =	
  "select	
  filme	
  from	
  Filme	
  filme";	
  
	
  	
  	
  	
  	
  	
  	
  	
  Query	
  query	
  =	
  em.createQuery(jpql);	
  
	
  	
  	
  	
  	
  	
  	
  	
  return	
  (List<Filme>)query.getResultList();	
  
	
  	
  	
  	
  }	
  
}
@Entity	
  
public	
  class	
  Filme	
  implements	
  Serializable	
  {	
  
	
  	
  	
  	
  @Id	
  private	
  Long	
  id;	
  
	
  	
  	
  	
  private	
  String	
  titulo;	
  
	
  	
  	
  	
  private	
  String	
  diretor;	
  
	
  	
  	
  	
  private	
  Long	
  ano;	
  
	
  	
  	
  	
  private	
  long	
  duracao;	
  
	
  	
  	
  	
  private	
  String	
  imdb;	
  
}
WEB-INF
web.xml
classes
FilmesServiceSoap.war
Deploy
Endpoint:

http://servidor/FilmesServiceSoap/FilmeFacadeService
Cliente SOAP
Com geração automática do
código SOAP
Ainda assim muito complexo:
a complexidade migrou para
a configuração
20
public	
  class	
  FilmeClient	
  {	
  
	
  	
  	
  	
  public	
  static	
  void	
  main(String[]	
  args)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  FilmeFacadeService	
  service	
  =	
  new	
  FilmeFacadeService();	
  
	
  	
  	
  	
  	
  	
  	
  	
  FilmeFacade	
  proxy	
  =	
  service.getFilmeFacadePort();	
  
	
  	
  	
  	
  	
  	
  	
  	
  listarFilmes(proxy.getFilmes());	
  
	
  	
  	
  	
  }	
  
	
  	
  	
  	
  	
  
	
  	
  	
  	
  public	
  static	
  void	
  listarFilmes(List<Filme>	
  filmes)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  for(Filme	
  f	
  :	
  filmes)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  System.out.println(f.getImdb()+":	
  "	
  +	
  f.getTitulo()	
  +	
  "("	
  +	
  f.getAno()	
  +	
  ")");	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  System.out.println("	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "	
  +	
  f.getDiretor());	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  System.out.println("	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "	
  +	
  f.getDuracao()	
  +	
  "	
  minutosn");	
  
	
  	
  	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  }	
  
} $	
  java	
  –jar	
  FilmeClient.jar	
  
tt0081505:	
  The	
  Shining(1980)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  Stanley	
  Kubrick	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  144	
  minutos	
  
tt1937390:	
  Nymphomaniac(2013)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  Lars	
  von	
  Trier	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  330	
  minutos	
  
tt0069293:	
  Solyaris(1972)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  Andrei	
  Tarkovsky	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  167	
  minutos	
  
tt1445520:	
  Hearat	
  Shulayim(2011)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  Joseph	
  Cedar
Cliente em container
21
@Named("filmesBean")	
  
public	
  class	
  FilmesManagedBean	
  {	
  
	
  	
  	
  	
  @WebServiceRef(wsdlLocation=

	
  	
  	
  	
  	
  	
  "http://localhost:8080/FilmesServiceSoap/FilmeFacadeService?wsdl")	
  
	
  	
  	
  	
  private	
  FilmeFacadeService	
  service;	
  	
  	
  	
  	
  
	
  	
  	
  	
  private	
  List<Filme>	
  filmes;	
  
	
  	
  	
  	
  	
  
	
  	
  	
  	
  @PostConstruct	
  
	
  	
  	
  	
  public	
  void	
  init()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  FilmeFacade	
  proxy	
  =	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  service.getFilmeFacadePort();	
  
	
  	
  	
  	
  	
  	
  	
  	
  this.filmes	
  =	
  proxy.getFilmes();	
  
	
  	
  	
  	
  }	
  
	
  	
  	
  	
  …	
  
}
<h1>Lista	
  de	
  Filmes</h1>	
  
<h:dataTable	
  value="#{filmesBean.filmes}"	
  var="filme”>	
  
	
  	
  	
  <h:column>	
  
	
  	
  	
  	
  	
  <f:facet	
  name="header">IMDB</f:facet>	
  
	
  	
  	
  	
  	
  <a	
  href="http://www.imdb.com/title/#{filme.imdb}">	
  	
  

	
  	
  	
  	
  	
  	
  #{filme.imdb}</a>	
  
	
  	
  	
  </h:column>	
  
	
  	
  	
  <h:column>	
  
	
  	
  	
  	
  	
  <f:facet	
  name="header">Título</f:facet>	
  
	
  	
  	
  	
  	
  	
  #{filme.titulo}	
  
	
  	
  	
  </h:column>	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ...	
  
</h:dataTable>
CDI Managed Bean
JSF Facelets
Mais simples. Menos configuração
RESTful Web Services
REST ~= Infraestrutura de um website
recursos (páginas), links, hierarquia
representações de dados e tipos (URIs, MIME)
vocabulário de operações do protocolo HTTP (GET, POST, …)
URIs ~= objetos
pais.estado.cidade	
  	
  
==
http://servidor/aplicacao/pais/estado/cidade/
Representações
XML, JSON, CSV, etc.
Métodos HTTP permitem operações CRUD
Create: POST /pais/estado (<estado>SP</estado>, no corpo)
Retrieve: GET /pais/estado/SP (Retrieve All com GET /pais/estado)
Update: PUT /pais/estado/PB
Delete: DELETE /pais/estado/PB
22
JAX-RS
JAX-RS : API Java para RESTful WebServices
Componentes
Subclasse de Application: configuração
Root resource class: fachada de serviços
Resource method: associados a métodos HTTP (@GET, @POST, etc.)
Providers: produzem ou consomem representações de entidades
em outros formatos (ex: XML, JSON)
JAX-RS usa anotações para configurar os componentes
@ApplicationPath na subclasse de Application
@Path nos Root resource classes
@GET, @POST, etc e @Path nos Resource methods
@Produces, @Consumes nos Providers
@Context para injetar diversos tipos de contexto do ambiente Web
23
Path templates e @PathParam
@Path templates

@Path("/filmes/{imdb}")	
  
Aceita por exemplo: http://abc.com/war/app/filmes/tt0066921
Parâmetros @PathParam

@Path("/filmes/{imdb}")	
  

public	
  class	
  FilmesIMDBResource	
  {	
  
	
  	
  	
  @GET	
  	
  @Produces("text/xml")

	
  	
  	
  public	
  Filme	
  getFilme(@PathParam("imdb")	
  String	
  codigoIMDB)	
  {	
  

	
  	
  	
  	
  	
  	
  return	
  entity.getFilmeByIMDBCode(codigoIMDB);
	
  	
  	
  }	
  
}	
  
24
Diferentes representações de objetos
25
Representação em JSON
{
"@numero": 145,
"nome": "Jeeves",
[ "telefone": {
"ddd": 11, "numero": 34567890
} ]
}
Representação em XML
<pessoa xmlns="http://pessoa" numero="145">
<nome>Jeeves</nome>
<telefone>
<ddd>11</ddd>
<numero>34567890</numero>
</telefone>
</pessoa>
Pessoa pessoa = new Pessoa();
pessoa.numero = 145;
pessoa.nome = "Jeeves";
pessoa.telefone[0] = new Telefone();
pessoa.telefone[0].ddd = 11;
pessoa.telefone[0].numero = 34567890;
class Pessoa {
int numero;
String nome;
Telefone[] telefones = 

new Telefone[3];
}
class Telefone {
int ddd;
int numero;
}
Classes
Objetos
em Java
application/xml application/json
JAXB
Java API for XML Binding
Mapeia classes Java a XML Schema
Classes mapeadas a XML Schema (ferramentas xjc e schemagen)
Objetos mapeados a documentos XML (através da API javax.xml.bind e
operações de serialização em XML (marshalling e unmarshalling)
XML
Schema
Classes
Java
Binding
xjc
schemagen
Documentos
(instâncias
XML)
Objetos
(instâncias
Java)
Marshalling
unmarshal()
marshal()
26
JAXB: exemplo de classe anotada
27
@XmlSchema(namespace	
  =	
  "http://filmes.argonavis.com/")	
  
package	
  com.argonavis.filmes.generated;	
  
@XmlRootElement	
  
public	
  class	
  Sala	
  implements	
  Serializable	
  {	
  
	
  	
  
	
  	
  	
  	
  private	
  List<Assento>	
  assentos;	
  
	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  private	
  String	
  nome;	
  
	
  	
  	
  	
  private	
  int	
  lotacao;	
  
	
  	
  	
  	
  @XmlElementWrapper	
  
	
  	
  	
  	
  @XmlElement(name="assento")	
  
	
  	
  	
  	
  public	
  List<Assento>	
  getAssentos()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  return	
  assentos;	
  
	
  	
  	
  	
  }	
  
…	
  
}
Sem @XmlElementWrapper
<sala>

	
  	
  	
  <assentos>…</assentos>

	
  	
  	
  <assentos>…</assentos>

</sala>	
  
Com @XmlElementWrapper
<sala>

	
  	
  	
  <assentos>

	
  	
  	
  	
  	
  	
  <assento>…</assento>

	
  	
  	
  	
  	
  	
  <assento>…</assento>

	
  	
  	
  </assentos>

</sala>
JAXB Marshal / Unmarshal
Unmarshalling = XML àJava
JAXBContext	
  jc	
  =	
  

	
  	
  	
  	
  	
  	
  JAXBContext.newInstance(	
  "com.argonavis.filmes.gen"	
  );	
  

Unmarshaller	
  u	
  =	
  jc.createUnmarshaller();	
  

Filme	
  filme	
  =	
  (Filme)u.unmarshal(	
  new	
  File(	
  "tt1937390.xml"	
  )	
  
);	
  	
  
Marshalling = Java àXML
JAXBContext	
  jc	
  =	
  	
  	
  	
  

	
  	
  	
  	
  	
  	
  JAXBContext.newInstance(	
  "com.argonavis.flmes.gen"	
  );

Filme	
  filme	
  =	
  ObjectFactory.createFilme();

filme.setAno(2014);	
  //	
  alterando	
  objeto

Marshaller	
  m	
  =	
  jc.createMarshaller();	
  

m.marshal(	
  filme,	
  System.out	
  );
28
JSON Binding!
Substituir o provedor JAXB default por EclipseLink MOXy:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
Configuração de JAXBContext
Map properties = new HashMap();
props.put("eclipselink.media-type", "application/json");
JAXBContext ctx = JAXBContext.newInstance(new Class[] { Produto.class }, props);
JSON à Java
UnMarshaller u = ctx.createUnMarshaller();
Produto produto= u.unmarshal(new StreamSource(“produto123.json”));
Java à JSON
Marshaller m = ctx.createMarshaller();
m.marshal(produto, System.out);
29
Haverá suporte nativo
a JSON binding no
Java EE 8 (2016)
Cliente REST com java.net
Cliente HTTP!
URL	
  url	
  =	
  new	
  URL("http://localhost:8080/ctx/app/imdb/tt0066921");	
  
HttpURLConnection	
  conn	
  =	
  (HttpURLConnection)	
  url.openConnection();	
  
conn.setRequestMethod("GET");	
  
conn.setRequestProperty("Accept",	
  "application/xml");	
  
if	
  (conn.getResponseCode()	
  !=	
  200)	
  	
  {	
  
	
  	
  	
  throw	
  new	
  RuntimeException("Erro	
  :	
  "	
  +	
  conn.getResponseCode());	
  
}	
  
	
  	
  
BufferedReader	
  br	
  =	
  

	
  	
  	
  	
  new	
  BufferedReader(new	
  InputStreamReader((conn.getInputStream())));	
  
String	
  linha	
  =	
  br.readLine();	
  
System.out.println("Dados	
  recebidos:	
  "	
  +	
  linha);	
  
conn.disconnect();	
  
JAXBContext	
  jc	
  =	
  JAXBContext.newInstance(Filme.class);	
  
Unmarshaller	
  u	
  =	
  jc.createUnmarshaller();	
  
Filme	
  filme	
  =	
  (Filme)	
  u.unmarshal(new	
  StringReader(linha));	
  
	
  	
  
System.out.println(filme.getIMDB());	
  …
30
Cliente Jersey*
Ainda mais simples
ClientConfig	
  config	
  =	
  

	
  	
  	
  	
  new	
  DefaultClientConfig();	
  
Client	
  client	
  =	
  Client.create(config);	
  
URI	
  baseURI	
  =	
  

	
  	
  	
  	
  UriBuilder.fromUri("http://localhost:8080/ctx").build();	
  
WebResource	
  service	
  =	
  client.resource(baseURI);	
  
Filme	
  filme	
  =	
  service.path("app")

	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  .path("filme/imdb/tt0066921")

	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  .accept(MediaType.APPLICATION_XML)	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  .get(Filme.class);	
  
System.out.println(filme.getIMDB());	
  
System.out.println(filme.getTitulo());	
  
System.out.println(filme.getDiretor());
* Existem outras alternativas. Veja RESTEasy
31
Cliente mobile (iPhone)
REST é melhor alternativa para Web Services que fazem
integração como outras plataformas
32
GET	
  http://192.168.1.25/festival/webapi/filme
Glassfish 4.0
1) Cliente REST escrito em Objective-C

rodando em iOS 7 gera requisição
2) Glassfish gera resposta HTTP
com lista de filmes em JSON
3) iPhone extrai dados e
preenche UITableView
O futuro
Java EE 8 promete uma vida menos complexa
API de segurança unificada
API de transações unificada
CDI com papel central em todas as aplicações
JSON binding nativo
Melhor integração com WebSockets
Mas, ...
A entropia continua a crescer... + linguagens + bugs +
problemas + ameaças + horizontes + iOT + ... a luta continua!
Fonte: http://tinyurl.com/7zlytsm
"the singularity is near!"Ray Kurzweil
helder@argonavis.com.br

Novas APIs do Java EE 7: JMS e Web Services

  • 1.
    Novas APIs do JavaEE 7 E a batalha contra a complexidade Helder da Rocha helder@argonavis.com.br
  • 2.
    Objetivos Falar um poucode complexidade do software e apresentar três APIs do Java EE 7 que simplificam o processo de desenvolvimento Conteúdo Breve reflexão sobre complexidade e entropia JMS 2.0 APIs de Web Services (SOAP e REST) O futuro? 2
  • 3.
    "A complexidade do softwareé uma propriedade 
 essencial, e não acidental" F. Brooks
  • 5.
    Ilusão da simplicidade Fonte:Booch Fonte: Grady Booch "Object Oriented Analysis and Design"
  • 6.
    Evolução das APIs UmaAPI deve ser a mais simples possível Contratos mais simples Menos burocracia Menos necessidade de documentação Mas… problema inerente ao software: complexidade Entropia sempre crescente Sucesso depende do controle da complexidade 6 1.0 2.0 3.0 1.0 1.0 2.0
  • 7.
    Java EE 7 Objetivosempre presente na evolução das APIs: Simplificar o uso! Menor curva de aprendizado Mais defaults, menos configuração Menos, menos, menos (até mesmo o JSF conseguiu ficar mais simples na Java EE 7 :-)
  • 8.
    Java Message Service1.0 Queue
 Connection
 Factory Queue
 Connection Queue
 Session Queue
 Sender Queue
 Receiver Message Queue createSession() jndi.lookup(queueFactory) createConnection() createMessage() create() create() receive()send() jndi.lookup(queue) API para enviar e receber mensagens usa classes e métodos diferentes para domínios Queue e Topic
  • 9.
    Java Message Service1.1 Connection
 Factory Connection SessionMessage
 Producer Message
 Consumer Message Destination createSession() jndi.lookup(factory) createConnection() createMessage() create() create() receive()send() jndi.lookup(destination) API para enviar e receber mensagens usa classes e métodos iguais para domínios Queue e Topic
  • 10.
    Java Message Service2.0 10 Connection
 Factory JMSContextJMSProducer JMSConsumer Message Destination @Inject factory createJMSContext() createMessage() create() create() receive()send() @Inject destination @Inject em vez de JNDI Menos código para enviar e receber mensagens
  • 11.
    Java Message Service2.0 11 Connection
 Factory JMSContext Destination @Inject factory createJMSContext() receive()send() @Inject destination Menos código! Menos código!
  • 12.
    Envio de mensagensJMS 2.0 Antes (JMS 1.1) JMS 2.0 12 public  void  sendJMS2(ConnectionFactory  conFactory,  Queue  queue,  String  text)  {        try  (JMSContext  context  =  conFactory.createContext();)  {              context.createProducer().send(queue,  text);        }  catch  (JMSRuntimeException  ex)  {  //  handle  exception  }   } public  void  sendJMS11(ConnectionFactory  conFactory,  Queue  queue,  String  text)  {        try  {  
            Connection  con  =  conFactory.createConnection();  
            try  {  
                  Session  session  =  con.createSession(false,Session.AUTO_ACKNOWLEDGE);  
                  MessageProducer  messageProducer  =  session.createProducer(queue);  
                  TextMessage  textMessage  =  session.createTextMessage(text);  
                  messageProducer.send(textMessage);  
            }  finally  {  
                  connection.close();  
            }  
      }  catch  (JMSException  ex)  {  //  handle  exception  }    }
  • 13.
    Recebimento síncrono JMS2.0 13 Antes (JMS 1.1) JMS 2.0 public  void  recJMS2(ConnectionFactory  conFactory,  Queue  queue,  String  text)  {        try  (JMSContext  context  =  conFactory.createContext();){              JMSConsumer  consumer  =  context.createConsumer(queue);  
            this.messageContents  =  consumer.receiveBody(String.class);
      }  catch  (JMSRuntimeException  ex)  {  //  handle  exception  }   } public  void  recJMS11(ConnectionFactory  conFactory,  Queue  queue,  String  text)  {        try  {  
            Connection  con  =  conFactory.createConnection();  
            try  {  
                  Session  session  =  con.createSession(false,Session.AUTO_ACKNOWLEDGE);  
                  MessageConsumer  messageConsumer  =  session.createConsumer(queue);  
                  con.start();  
                  TextMessage  textMessage  =  (TextMessage)messageConsumer.receive();  
                  this.messageContents  =  textMessage.getText();
            }  finally  {  
                  connection.close();  
            }  
      }  catch  (JMSException  ex)  {  //  handle  exception  }   }
  • 14.
    Pré-história do SOAP,parte 1
 No princípio, Web Service eram simples de codificar em XML POST /ISBNService.jsp HTTP/1.0 Content-type: text/xml
 Content-length: 90 <chamada>
 <funcao> <nome>getPrice</nome> <param>2877142566</param> </funcao> </chamada> HTTP/1.1 200 OK Content-type: text/xml
 Content-length: 77 <resposta>
 <funcao> <param>19.50</param> </funcao> </resposta> ISBNService.jsp ISBNClient ISBNQuery getPrice() 2877142566 19.50 BD 1 2 3 4 gera requisição gera resposta 14
  • 15.
    Pré-história do SOAPparte 2 XML-RPC: padronização dos tags para operações, parâmetros, tipos, etc. Criado no grupo de discussões xml-dev em 1998 <methodCall>
 <methodName>getPrice</methodName>
 <params> <param> <value><string>2877142566</string></value> </param> </param> </methodCall> <methodResponse>
 <params> <param> <value><double>19.5</double></value> </param> </param> </methodResponse> Resposta Requisição 15
  • 16.
    “Simples” requisição SOAP-RPC POST/xmlrpc-bookstore/bookpoint/BookstoreIF HTTP/1.0 Content-Type: text/xml; charset="utf-8" Content-Length: 585 SOAPAction: "" <?xml version="1.0" encoding="UTF-8"?> <env:Envelope xmlns:env="http://www.w3.org/2001/12/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://www.w3.org/2001/12/soap-encoding/" env:encodingStyle="http://www.w3.org/2001/12/soap-encoding/"> <env:Body> <ans1:getPrice xmlns:ans1="http://mybooks.org/wsdl"> <String_1 xsi:type="xsd:string">2877142566</String_1> </ans1:getPrice> </env:Body> </env:Envelope> Parâmetro (ISBN) Payload Mensagem (envelope) SOAP 16 Padronização oficial Muito mais burocrática
  • 17.
    Resposta SOAP-RPC HTTP/1.1 200OK Content-Type: text/xml; charset="utf-8" SOAPAction: "" Date: Thu, 08 Aug 2002 01:48:22 GMT Server: Apache Coyote HTTP/1.1 Connector [1.0] Connection: close <?xml version="1.0" encoding="UTF-8"?> <env:Envelope 
 xmlns:env="http://www.w3.org/2001/12/soap-envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://www.w3.org/2001/12/soap-encoding/" xmlns:ns0="http://mybooks.org/types" env:encodingStyle="http://www.w3.org/2001/12/soap-encoding/"> <env:Body> <ans1:getPriceResponse xmlns:ans1="http://mybooks.org/wsdl"> <result xsi:type="xsd:decimal">19.50</result> </ans1:getPriceResponse> </env:Body> </env:Envelope> Resposta (Preço) Payload Mensagem (envelope) SOAP 17
  • 18.
    WSDL para descrevero serviço Compare  com  a   mensagem  SOAP   mostrada   anteriormente Informa  onde  está  o  serviço  (endpoint) <?xml  version="1.0"  encoding="UTF-­‐8"?>   <definitions  name="BookstoreService"  
        targetNamespace="http://mybooks.org/wsdl"          xmlns:tns="http://mybooks.org/wsdl"          xmlns="http://schemas.xmlsoap.org/wsdl/"          xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"          xmlns:xsd="http://www.w3.org/2001/XMLSchema">          <types>...</types>        <message  name="BookstoreIF_getPrice">              <part  name="String_1"  type="xsd:string"/>        </message>        <message  name="BookstoreIF_getPriceResponse">              <part  name="result"  type="xsd:decimal"/>        </message>        <portType  name="BookstoreIF">                <operation  name="getPrice"  parameterOrder="String_1">                          <input  message="tns:BookstoreIF_getPrice"/>                    <output  message="tns:BookstoreIF_getPriceResponse"/>                </operation>        </portType>          <binding  ...  >  ...</binding>          <service  ...  >  ...  </service>     </definitions>  
  • 19.
    Simplificação com JAX-WS
 (escondendoa complexidade do XML) 19 @WebService   public  class  FilmeFacade  {          @PersistenceContext(unitName  =  "FilmesServiceSoap")          EntityManager  em;                    public  List<Filme>  getFilmes()  {                  String  jpql  =  "select  filme  from  Filme  filme";                  Query  query  =  em.createQuery(jpql);                  return  (List<Filme>)query.getResultList();          }   } @Entity   public  class  Filme  implements  Serializable  {          @Id  private  Long  id;          private  String  titulo;          private  String  diretor;          private  Long  ano;          private  long  duracao;          private  String  imdb;   } WEB-INF web.xml classes FilmesServiceSoap.war Deploy Endpoint:
 http://servidor/FilmesServiceSoap/FilmeFacadeService
  • 20.
    Cliente SOAP Com geraçãoautomática do código SOAP Ainda assim muito complexo: a complexidade migrou para a configuração 20 public  class  FilmeClient  {          public  static  void  main(String[]  args)  {                  FilmeFacadeService  service  =  new  FilmeFacadeService();                  FilmeFacade  proxy  =  service.getFilmeFacadePort();                  listarFilmes(proxy.getFilmes());          }                    public  static  void  listarFilmes(List<Filme>  filmes)  {                  for(Filme  f  :  filmes)  {                          System.out.println(f.getImdb()+":  "  +  f.getTitulo()  +  "("  +  f.getAno()  +  ")");                          System.out.println("                            "  +  f.getDiretor());                          System.out.println("                            "  +  f.getDuracao()  +  "  minutosn");                  }          }   } $  java  –jar  FilmeClient.jar   tt0081505:  The  Shining(1980)                        Stanley  Kubrick                        144  minutos   tt1937390:  Nymphomaniac(2013)                        Lars  von  Trier                        330  minutos   tt0069293:  Solyaris(1972)                        Andrei  Tarkovsky                        167  minutos   tt1445520:  Hearat  Shulayim(2011)                        Joseph  Cedar
  • 21.
    Cliente em container 21 @Named("filmesBean")   public  class  FilmesManagedBean  {          @WebServiceRef(wsdlLocation=
            "http://localhost:8080/FilmesServiceSoap/FilmeFacadeService?wsdl")          private  FilmeFacadeService  service;                  private  List<Filme>  filmes;                    @PostConstruct          public  void  init()  {                  FilmeFacade  proxy  =                          service.getFilmeFacadePort();                  this.filmes  =  proxy.getFilmes();          }          …   } <h1>Lista  de  Filmes</h1>   <h:dataTable  value="#{filmesBean.filmes}"  var="filme”>        <h:column>            <f:facet  name="header">IMDB</f:facet>            <a  href="http://www.imdb.com/title/#{filme.imdb}">    
            #{filme.imdb}</a>        </h:column>        <h:column>            <f:facet  name="header">Título</f:facet>              #{filme.titulo}        </h:column>                          ...   </h:dataTable> CDI Managed Bean JSF Facelets Mais simples. Menos configuração
  • 22.
    RESTful Web Services REST~= Infraestrutura de um website recursos (páginas), links, hierarquia representações de dados e tipos (URIs, MIME) vocabulário de operações do protocolo HTTP (GET, POST, …) URIs ~= objetos pais.estado.cidade     == http://servidor/aplicacao/pais/estado/cidade/ Representações XML, JSON, CSV, etc. Métodos HTTP permitem operações CRUD Create: POST /pais/estado (<estado>SP</estado>, no corpo) Retrieve: GET /pais/estado/SP (Retrieve All com GET /pais/estado) Update: PUT /pais/estado/PB Delete: DELETE /pais/estado/PB 22
  • 23.
    JAX-RS JAX-RS : APIJava para RESTful WebServices Componentes Subclasse de Application: configuração Root resource class: fachada de serviços Resource method: associados a métodos HTTP (@GET, @POST, etc.) Providers: produzem ou consomem representações de entidades em outros formatos (ex: XML, JSON) JAX-RS usa anotações para configurar os componentes @ApplicationPath na subclasse de Application @Path nos Root resource classes @GET, @POST, etc e @Path nos Resource methods @Produces, @Consumes nos Providers @Context para injetar diversos tipos de contexto do ambiente Web 23
  • 24.
    Path templates e@PathParam @Path templates
 @Path("/filmes/{imdb}")   Aceita por exemplo: http://abc.com/war/app/filmes/tt0066921 Parâmetros @PathParam
 @Path("/filmes/{imdb}")  
 public  class  FilmesIMDBResource  {        @GET    @Produces("text/xml")
      public  Filme  getFilme(@PathParam("imdb")  String  codigoIMDB)  {  
            return  entity.getFilmeByIMDBCode(codigoIMDB);      }   }   24
  • 25.
    Diferentes representações deobjetos 25 Representação em JSON { "@numero": 145, "nome": "Jeeves", [ "telefone": { "ddd": 11, "numero": 34567890 } ] } Representação em XML <pessoa xmlns="http://pessoa" numero="145"> <nome>Jeeves</nome> <telefone> <ddd>11</ddd> <numero>34567890</numero> </telefone> </pessoa> Pessoa pessoa = new Pessoa(); pessoa.numero = 145; pessoa.nome = "Jeeves"; pessoa.telefone[0] = new Telefone(); pessoa.telefone[0].ddd = 11; pessoa.telefone[0].numero = 34567890; class Pessoa { int numero; String nome; Telefone[] telefones = 
 new Telefone[3]; } class Telefone { int ddd; int numero; } Classes Objetos em Java application/xml application/json
  • 26.
    JAXB Java API forXML Binding Mapeia classes Java a XML Schema Classes mapeadas a XML Schema (ferramentas xjc e schemagen) Objetos mapeados a documentos XML (através da API javax.xml.bind e operações de serialização em XML (marshalling e unmarshalling) XML Schema Classes Java Binding xjc schemagen Documentos (instâncias XML) Objetos (instâncias Java) Marshalling unmarshal() marshal() 26
  • 27.
    JAXB: exemplo declasse anotada 27 @XmlSchema(namespace  =  "http://filmes.argonavis.com/")   package  com.argonavis.filmes.generated;   @XmlRootElement   public  class  Sala  implements  Serializable  {              private  List<Assento>  assentos;                        private  String  nome;          private  int  lotacao;          @XmlElementWrapper          @XmlElement(name="assento")          public  List<Assento>  getAssentos()  {                  return  assentos;          }   …   } Sem @XmlElementWrapper <sala>
      <assentos>…</assentos>
      <assentos>…</assentos>
 </sala>   Com @XmlElementWrapper <sala>
      <assentos>
            <assento>…</assento>
            <assento>…</assento>
      </assentos>
 </sala>
  • 28.
    JAXB Marshal /Unmarshal Unmarshalling = XML àJava JAXBContext  jc  =  
            JAXBContext.newInstance(  "com.argonavis.filmes.gen"  );  
 Unmarshaller  u  =  jc.createUnmarshaller();  
 Filme  filme  =  (Filme)u.unmarshal(  new  File(  "tt1937390.xml"  )   );     Marshalling = Java àXML JAXBContext  jc  =        
            JAXBContext.newInstance(  "com.argonavis.flmes.gen"  );
 Filme  filme  =  ObjectFactory.createFilme();
 filme.setAno(2014);  //  alterando  objeto
 Marshaller  m  =  jc.createMarshaller();  
 m.marshal(  filme,  System.out  ); 28
  • 29.
    JSON Binding! Substituir oprovedor JAXB default por EclipseLink MOXy: javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory Configuração de JAXBContext Map properties = new HashMap(); props.put("eclipselink.media-type", "application/json"); JAXBContext ctx = JAXBContext.newInstance(new Class[] { Produto.class }, props); JSON à Java UnMarshaller u = ctx.createUnMarshaller(); Produto produto= u.unmarshal(new StreamSource(“produto123.json”)); Java à JSON Marshaller m = ctx.createMarshaller(); m.marshal(produto, System.out); 29 Haverá suporte nativo a JSON binding no Java EE 8 (2016)
  • 30.
    Cliente REST comjava.net Cliente HTTP! URL  url  =  new  URL("http://localhost:8080/ctx/app/imdb/tt0066921");   HttpURLConnection  conn  =  (HttpURLConnection)  url.openConnection();   conn.setRequestMethod("GET");   conn.setRequestProperty("Accept",  "application/xml");   if  (conn.getResponseCode()  !=  200)    {        throw  new  RuntimeException("Erro  :  "  +  conn.getResponseCode());   }       BufferedReader  br  =  
        new  BufferedReader(new  InputStreamReader((conn.getInputStream())));   String  linha  =  br.readLine();   System.out.println("Dados  recebidos:  "  +  linha);   conn.disconnect();   JAXBContext  jc  =  JAXBContext.newInstance(Filme.class);   Unmarshaller  u  =  jc.createUnmarshaller();   Filme  filme  =  (Filme)  u.unmarshal(new  StringReader(linha));       System.out.println(filme.getIMDB());  … 30
  • 31.
    Cliente Jersey* Ainda maissimples ClientConfig  config  =  
        new  DefaultClientConfig();   Client  client  =  Client.create(config);   URI  baseURI  =  
        UriBuilder.fromUri("http://localhost:8080/ctx").build();   WebResource  service  =  client.resource(baseURI);   Filme  filme  =  service.path("app")
                          .path("filme/imdb/tt0066921")
                          .accept(MediaType.APPLICATION_XML)                            .get(Filme.class);   System.out.println(filme.getIMDB());   System.out.println(filme.getTitulo());   System.out.println(filme.getDiretor()); * Existem outras alternativas. Veja RESTEasy 31
  • 32.
    Cliente mobile (iPhone) RESTé melhor alternativa para Web Services que fazem integração como outras plataformas 32 GET  http://192.168.1.25/festival/webapi/filme Glassfish 4.0 1) Cliente REST escrito em Objective-C
 rodando em iOS 7 gera requisição 2) Glassfish gera resposta HTTP com lista de filmes em JSON 3) iPhone extrai dados e preenche UITableView
  • 33.
    O futuro Java EE8 promete uma vida menos complexa API de segurança unificada API de transações unificada CDI com papel central em todas as aplicações JSON binding nativo Melhor integração com WebSockets Mas, ... A entropia continua a crescer... + linguagens + bugs + problemas + ameaças + horizontes + iOT + ... a luta continua!
  • 34.
    Fonte: http://tinyurl.com/7zlytsm "the singularityis near!"Ray Kurzweil helder@argonavis.com.br