Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
JSR 339
Java API for RESTful Web Services
GujavaSC / Adopt a JSR
Membros do GujavaSC
Participação Adopt a JSR
Grupo de estudos
Artigos
Palestras
O que é REST?
É um estilo arquitetural…
Estilo arquitetural???
É um estilo arquitetural…
Enxaimel
Telhado
Madeiras
Tijolos
Estilo
Arquitetural
REST
HTTP
Características
Recursos são identificados por um ID;
Sem estado;
Vincule as coisas;
Múltiplas representações;
Interface u...
Características
Recursos são identificados por um ID;
Sem estado;
Vincule as coisas;
Múltiplas representações;
Interface u...
Interface Uniforme
Verbos HTTP Ação
POST Cria um novo recurso
PUT Atualiza um recurso
DELETE Remove um recurso
GET Retorna...
JAX-RS 1.x
Final Release em 2008
Objetivos
Baseado em POJO
Centralizado em HTTP
Independência de formato
Independência de ...
Exemplo JAX-RS 1.0
@Path("books")
public class BookResource {
@GET
@Path("/year/{year}")
@Produces(MediaType.APPLICATION_J...
Exemplo JAX-RS 1.0
http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
@Path("books")
public class Boo...
Exemplo JAX-RS 1.0
http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
@Path("books")
public class Boo...
@Path("books")
public class BookResource {
@GET
@Path("/year/{year}")
@Produces(MediaType.APPLICATION_JSON)
public Respons...
Exemplo JAX-RS 1.0
@Path("books")
public class BookResource {
@GET
@Path("/year/{year}")
@Produces(MediaType.APPLICATION_J...
Exemplo JAX-RS 1.0
@Path("books")
public class BookResource {
@GET
@Path("/year/{year}")
@Produces(MediaType.APPLICATION_J...
Exemplo JAX-RS 1.0
@Path("books")
public class BookResource {
@GET
@Path("/year/{year}")
@Produces(MediaType.APPLICATION_J...
Exemplo JAX-RS 1.0
@Path("books")
public class BookResource {
@GET
@Path("/year/{year}")
@Produces(MediaType.APPLICATION_J...
Exemplo JAX-RS 1.0
@Path("books")
public class BookResource {
@GET
@Path("/year/{year}")
@Produces(MediaType.APPLICATION_J...
Exemplo JAX-RS 1.0
@Path("books")
public class BookResource {
@GET
@Path("/year/{year}")
@Produces(MediaType.APPLICATION_J...
JAX-RS 2.0
Final Release em Maio de 2013
Solicitações (JSR 339)
Client API
Asynchronous processing
Filters / Interceptors
...
Client API
Client API
Baseada na API do Jersey (versão 1.x);
Consumir serviços criados em qualquer linguagem.
Qual é o recurso?
Book!
Como foi exposto?
@Path("books")
public class BookResource {
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response read(@...
Como consultávamos?
@Test
public void deveConterOLivro_javaee6() throws Exception {
URL url = new URL("http://localhost:8080/rest-example/reso...
@Test
public void deveConterOLivro_javaee6() throws Exception {
URL url = new URL("http://localhost:8080/rest-example/reso...
@Test
public void deveConterOLivro_javaee6() throws Exception {
URL url = new URL("http://localhost:8080/rest-example/reso...
@Test
public void deveConterOLivro_javaee6() throws Exception {
URL url = new URL("http://localhost:8080/rest-example/reso...
@Test
public void deveConterOLivro_javaee6() throws Exception {
URL url = new URL("http://localhost:8080/rest-example/reso...
@Test
public void deveConterOLivro_javaee6() throws Exception {
URL url = new URL("http://localhost:8080/rest-example/reso...
@Test
public void deveConterOLivro_javaee6() throws Exception {
URL url = new URL("http://localhost:8080/rest-example/reso...
@Test
public void deveConterOLivro_javaee6() throws Exception {
URL url = new URL("http://localhost:8080/rest-example/reso...
E agora com a Client API?
@Test
public void deveConterOLivro_javaee7() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target...
@Test
public void deveConterOLivro_javaee7() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target...
@Test
public void deveConterOLivro_javaee7() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target...
@Test
public void deveConterOLivro_javaee7() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target...
@Test
public void deveConterOLivro_javaee7() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target...
@Test
public void deveConterOLivro_javaee7() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target...
@Test
public void deveConterOLivro_javaee7() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target...
@Test
public void deveConterOLivro_javaee7() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target...
@Test
public void deveConterOLivro_javaee7() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target...
...“um pouco” mais fluente...
@Test
public void deveConterOLivro_javaee7() {
Client client = ClientBuilder.newClient();
Book book = client.target("http:...
...@Delete...
@Test
public void deletarOLivro_javaee7() {
Client client = ClientBuilder.newClient();
Response res = client.target("http:...
@Test
public void deletarOLivro_javaee7() {
Client client = ClientBuilder.newClient();
Response res = client.target("http:...
@Test
public void deletarOLivro_javaee7() {
Client client = ClientBuilder.newClient();
Response res = client.target("http:...
@Test
public void deletarOLivro_javaee7() {
Client client = ClientBuilder.newClient();
Response res = client.target("http:...
...@Post...
@Test
public void inserirOLivro_javaee7() {
Client client = ClientBuilder.newClient();
Book book = new Book(1, "Android", ...
@Test
public void inserirOLivro_javaee7() {
Client client = ClientBuilder.newClient();
Book book = new Book(1, "Android", ...
@Test
public void inserirOLivro_javaee7() {
Client client = ClientBuilder.newClient();
Book book = new Book(1, "Android", ...
@Test
public void inserirOLivro_javaee7() {
Client client = ClientBuilder.newClient();
Book book = new Book(1, "Android", ...
Como configurar
Filters e Interceptors?
@Test
public void inserirOLivroComFiltroDeLog() {
Client client = ClientBuilder.newClient();
client.register(MyLoggingFilt...
@Test
public void inserirOLivroComFiltroDeLog() {
Client client = ClientBuilder.newClient();
client.register(MyLoggingFilt...
@Test
public void inserirOLivroComFiltroDeLog() {
Client client = ClientBuilder.newClient();
client.register(MyLoggingFilt...
@Test
public void inserirOLivroComFiltroDeLog() {
Client client = ClientBuilder.newClient();
client.register(MyLoggingFilt...
Asynchronous
Processing
Que tal uma chamada assíncrona?
@Path("books")
public class BookResource {
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response read(@...
@Path("books")
public class BookResource {
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response read(@...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
Timeout no método get()
JSR 236 - Concurrency Utilities for JavaTM EE
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
Posso enviar um InvocationCallback?
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
@Test
public void buscaOLivroDeFormaAssincrona() {
WebTarget target = ClientBuilder.newClient()
.target("http://localhost:...
Assíncrono no servidor...
...se você quiser!
Primeiro, sem EJB...
@Path("async/books")
public class AsyncBookResource {
@GET
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public void lo...
@Path("async/books")
public class AsyncBookResource {
@GET
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public void lo...
@Path("async/books")
public class AsyncBookResource {
@GET
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public void lo...
@Path("async/books")
public class AsyncBookResource {
@GET
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public void lo...
@Path("async/books")
public class AsyncBookResource {
@GET
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public void lo...
@Path("async/books")
public class AsyncBookResource {
@GET
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public void lo...
E se for com EJB?
@Stateless
@Path("async/books")
public class AsyncBookResource {
@GET
@Path("/")
@Asynchronous
@Produces(MediaType.APPLICA...
@Stateless
@Path("async/books")
public class AsyncBookResource {
@GET
@Path("/")
@Asynchronous
@Produces(MediaType.APPLICA...
@Stateless
@Path("async/books")
public class AsyncBookResource {
@GET
@Path("/")
@Asynchronous
@Produces(MediaType.APPLICA...
@Stateless
@Path("async/books")
public class AsyncBookResource {
@GET
@Path("/")
@Asynchronous
@Produces(MediaType.APPLICA...
Filters and
Interceptors
O que são os filters?
ClientRequestFilter
ClientResponseFilter
@Provider
public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter {
public void filter(ClientReque...
@Provider
public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter {
public void filter(ClientReque...
@Provider
public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter {
public void filter(ClientReque...
@Provider
public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter {
public void filter(ClientReque...
@Provider
public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter {
public void filter(ClientReque...
ContainerRequestFilter
ContainerResponserFilter
@Provider
class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter {
public void filter(ContainerReq...
@Provider
class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter {
public void filter(ContainerReq...
@Provider
class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter {
public void filter(ContainerReq...
@Provider
class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter {
public void filter(ContainerReq...
@Provider
class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter {
public void filter(ContainerReq...
O que são os interceptors?
ReaderInterceptor
WriterInterceptor
Descompactando a requisição
@Provider
public class GzipReaderInterceptor implements ReaderInterceptor {
Object aroundReadFrom(ReaderInterceptorContext...
@Provider
public class GzipReaderInterceptor implements ReaderInterceptor {
Object aroundReadFrom(ReaderInterceptorContext...
@Provider
public class GzipReaderInterceptor implements ReaderInterceptor {
Object aroundReadFrom(ReaderInterceptorContext...
@Provider
public class GzipReaderInterceptor implements ReaderInterceptor {
Object aroundReadFrom(ReaderInterceptorContext...
Compactando a resposta
@Provider
public class GzipWriteInterceptor implements WriteInterceptor {
void aroundWriteTo(WriterInterceptorContext ctx)...
@Provider
public class GzipWriteInterceptor implements WriteInterceptor {
void aroundWriteTo(WriterInterceptorContext ctx)...
@Provider
public class GzipWriteInterceptor implements WriteInterceptor {
void aroundWriteTo(WriterInterceptorContext ctx)...
@Provider
public class GzipWriteInterceptor implements WriteInterceptor {
void aroundWriteTo(WriterInterceptorContext ctx)...
Mas, qual é a diferença
mesmo?
Filters: Acesso ao contexto do
request/response.
Exemplo de Filters
Logar origem do request.
Verificar qual o método http utilizado.
Qual a URI.
Interceptors: Acesso ao contexto da
mensagem.
Exemplo de Interceptors
Compactar o conteúdo da mensagem a ser enviada.
Descompactar o conteúdo da mensagem a ser lida.
Posso logar minhas requisições
antes de chegar ao método?
@PreMatching
@Provider
@PreMatching
public class HttpPreMatchingFilter implements ContainerRequestFilter {
public void filter(Container...
@Provider
@PreMatching
public class HttpPreMatchingFilter implements ContainerRequestFilter {
public void filter(Container...
@Provider
@PreMatching
public class HttpPreMatchingFilter implements ContainerRequestFilter {
public void filter(Container...
Mas se eu quiser logar um
método específico, é possível?
@NameBinding
@NameBinding
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(value = RetentionPolicy.RUNTIME)
public @interfa...
@Provider @Logged
public class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter {
...
}
@Path("/")
public class MyResourceClass {
@GET
@Logged
@Path("{name}")
@Produces("text/plain")
public String hello(@PathPa...
E a ordem? Posso definir?
@Priority
@Provider
@Authenticated
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerReques...
Modifier and Type Constant Field Value
public static final int AUTHENTICATION 1000
public static final int AUTHORIZATION 2...
Bean Validation
JSR-349
Como eu aplico?
public class Book {
private Integer id;
@NotNull
private String name;
private String description;
private Integer year;
pr...
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response create(@Valid Book book) {
ResponseBuilder rb = Response.ok(cr...
@GET
@Path("/year/{year}")
@Produces(MediaType.APPLICATION_JSON)
public Response listByYearAndName(@Max(2015) @PathParam("...
HATEOAS
Hipermídia como motor do estado do aplicativo
“If the engine of application is not being driven
by hypertext, then...
Book Purchase
Related
Books
Author
Receipt
/books/1/author
/books/genre/programming
/books/1/purchase
/books/1/purchase/12...
Link: <http://gujavasc.org/resources/books/1/purchase>; rel=purchase, …
<book>
<id>1</id>
<year>2013</year>
<name>REST in ...
Links Transicionais
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response read(@PathParam("id") Integer...
Links Transicionais
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response read(@PathParam("id") Integer...
Links Transicionais
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response read(@PathParam("id") Integer...
Links Transicionais
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response read(@PathParam("id") Integer...
Links Transicionais
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response read(@PathParam("id") Integer...
Links Transicionais
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response read(@PathParam("id") Integer...
Links Transicionais
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response read(@PathParam("id") Integer...
Links Transicionais
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response read(@PathParam("id") Integer...
Integração com Java EE
Managed Beans
CDI
EJB
Bean Validation
JSON API
OBRIGADO!
Daniel Cunha (Soro) - @dvlc_
Ivan Junckes Filho - @ivanjunckes
Ricardo Longa - @ricardolonga
https://github.com/...
Upcoming SlideShare
Loading in …5
×

JSR 339 - Java API for RESTful Web Services

1,310 views

Published on

Esta palestra é fruto da iniciativa de adoção da JSR 339 pelo Grupo de Usuários Java de SC. Foi apresentada no The Developers Conference 2014 (Florianópolis). Trata das novidades da JAX-RS 2 em relação a especificação anterior.

  • Nice !! Download 100 % Free Ebooks, PPts, Study Notes, Novels, etc @ https://www.ThesisScientist.com
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

JSR 339 - Java API for RESTful Web Services

  1. 1. JSR 339 Java API for RESTful Web Services
  2. 2. GujavaSC / Adopt a JSR Membros do GujavaSC Participação Adopt a JSR Grupo de estudos Artigos Palestras
  3. 3. O que é REST?
  4. 4. É um estilo arquitetural…
  5. 5. Estilo arquitetural??? É um estilo arquitetural…
  6. 6. Enxaimel Telhado Madeiras Tijolos
  7. 7. Estilo Arquitetural REST HTTP
  8. 8. Características Recursos são identificados por um ID; Sem estado; Vincule as coisas; Múltiplas representações; Interface uniforme.
  9. 9. Características Recursos são identificados por um ID; Sem estado; Vincule as coisas; Múltiplas representações; Interface uniforme.
  10. 10. Interface Uniforme Verbos HTTP Ação POST Cria um novo recurso PUT Atualiza um recurso DELETE Remove um recurso GET Retorna um recurso
  11. 11. JAX-RS 1.x Final Release em 2008 Objetivos Baseado em POJO Centralizado em HTTP Independência de formato Independência de container Inclusão no Java EE 6
  12. 12. Exemplo JAX-RS 1.0 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  13. 13. Exemplo JAX-RS 1.0 http://localhost:8080/rest-example/resources/books/year/2011?name=Book1 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } }
  14. 14. Exemplo JAX-RS 1.0 http://localhost:8080/rest-example/resources/books/year/2011?name=Book1 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } }
  15. 15. @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } } Exemplo JAX-RS 1.0 http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  16. 16. Exemplo JAX-RS 1.0 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  17. 17. Exemplo JAX-RS 1.0 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  18. 18. Exemplo JAX-RS 1.0 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  19. 19. Exemplo JAX-RS 1.0 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  20. 20. Exemplo JAX-RS 1.0 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  21. 21. Exemplo JAX-RS 1.0 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public List<Book> listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); // ResponseBuilder rb = Response.ok(books); // return rb.build(); return books; } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  22. 22. JAX-RS 2.0 Final Release em Maio de 2013 Solicitações (JSR 339) Client API Asynchronous processing Filters / Interceptors Bean Validation Hypermedia MVC
  23. 23. Client API
  24. 24. Client API Baseada na API do Jersey (versão 1.x); Consumir serviços criados em qualquer linguagem.
  25. 25. Qual é o recurso?
  26. 26. Book!
  27. 27. Como foi exposto?
  28. 28. @Path("books") public class BookResource { @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id) { return Response.ok(readObject(id)).build(); } } http://localhost:8080/rest-example/resources/books/10
  29. 29. Como consultávamos?
  30. 30. @Test public void deveConterOLivro_javaee6() throws Exception { URL url = new URL("http://localhost:8080/rest-example/resources/books/10"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); String result = IOUtils.toString(con.getInputStream(), "UTF-8"); con.disconnect(); Book book = new Gson().fromJson(result, Book.class); assertThat(book, notNullValue()); }
  31. 31. @Test public void deveConterOLivro_javaee6() throws Exception { URL url = new URL("http://localhost:8080/rest-example/resources/books/10"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); String result = IOUtils.toString(con.getInputStream(), "UTF-8"); con.disconnect(); Book book = new Gson().fromJson(result, Book.class); assertThat(book, notNullValue()); }
  32. 32. @Test public void deveConterOLivro_javaee6() throws Exception { URL url = new URL("http://localhost:8080/rest-example/resources/books/10"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); String result = IOUtils.toString(con.getInputStream(), "UTF-8"); con.disconnect(); Book book = new Gson().fromJson(result, Book.class); assertThat(book, notNullValue()); }
  33. 33. @Test public void deveConterOLivro_javaee6() throws Exception { URL url = new URL("http://localhost:8080/rest-example/resources/books/10"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); String result = IOUtils.toString(con.getInputStream(), "UTF-8"); con.disconnect(); Book book = new Gson().fromJson(result, Book.class); assertThat(book, notNullValue()); }
  34. 34. @Test public void deveConterOLivro_javaee6() throws Exception { URL url = new URL("http://localhost:8080/rest-example/resources/books/10"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); String result = IOUtils.toString(con.getInputStream(), "UTF-8"); con.disconnect(); Book book = new Gson().fromJson(result, Book.class); assertThat(book, notNullValue()); }
  35. 35. @Test public void deveConterOLivro_javaee6() throws Exception { URL url = new URL("http://localhost:8080/rest-example/resources/books/10"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); String result = IOUtils.toString(con.getInputStream(), "UTF-8"); con.disconnect(); Book book = new Gson().fromJson(result, Book.class); assertThat(book, notNullValue()); }
  36. 36. @Test public void deveConterOLivro_javaee6() throws Exception { URL url = new URL("http://localhost:8080/rest-example/resources/books/10"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); String result = IOUtils.toString(con.getInputStream(), "UTF-8"); con.disconnect(); Book book = new Gson().fromJson(result, Book.class); assertThat(book, notNullValue()); } GSON, Jackson, Jettison, XStream
  37. 37. @Test public void deveConterOLivro_javaee6() throws Exception { URL url = new URL("http://localhost:8080/rest-example/resources/books/10"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); String result = IOUtils.toString(con.getInputStream(), "UTF-8"); con.disconnect(); Book book = new Gson().fromJson(result, Book.class); assertThat(book, notNullValue()); }
  38. 38. E agora com a Client API?
  39. 39. @Test public void deveConterOLivro_javaee7() { Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://localhost:8080/rest-example/resources"); WebTarget path = target.path("books/{id}"); WebTarget bookId = path.resolveTemplate("id", "10"); Builder invocation = bookId.request(); Book book = invocation.get(Book.class); client.close(); assertThat(book, notNullValue()); }
  40. 40. @Test public void deveConterOLivro_javaee7() { Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://localhost:8080/rest-example/resources"); WebTarget path = target.path("books/{id}"); WebTarget bookId = path.resolveTemplate("id", "10"); Builder invocation = bookId.request(); Book book = invocation.get(Book.class); client.close(); assertThat(book, notNullValue()); }
  41. 41. @Test public void deveConterOLivro_javaee7() { Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://localhost:8080/rest-example/resources"); WebTarget path = target.path("books/{id}"); WebTarget bookId = path.resolveTemplate("id", "10"); Builder invocation = bookId.request(); Book book = invocation.get(Book.class); client.close(); assertThat(book, notNullValue()); }
  42. 42. @Test public void deveConterOLivro_javaee7() { Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://localhost:8080/rest-example/resources"); WebTarget path = target.path("books/{id}"); WebTarget bookId = path.resolveTemplate("id", "10"); Builder invocation = bookId.request(); Book book = invocation.get(Book.class); client.close(); assertThat(book, notNullValue()); }
  43. 43. @Test public void deveConterOLivro_javaee7() { Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://localhost:8080/rest-example/resources"); WebTarget path = target.path("books/{id}"); WebTarget bookId = path.resolveTemplate("id", "10"); Builder invocation = bookId.request(); Book book = invocation.get(Book.class); client.close(); assertThat(book, notNullValue()); }
  44. 44. @Test public void deveConterOLivro_javaee7() { Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://localhost:8080/rest-example/resources"); WebTarget path = target.path("books/{id}"); WebTarget bookId = path.resolveTemplate("id", "10"); Builder invocation = bookId.request(); Book book = invocation.get(Book.class); client.close(); assertThat(book, notNullValue()); }
  45. 45. @Test public void deveConterOLivro_javaee7() { Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://localhost:8080/rest-example/resources"); WebTarget path = target.path("books/{id}"); WebTarget bookId = path.resolveTemplate("id", "10"); Builder invocation = bookId.request(); Book book = invocation.get(Book.class); client.close(); assertThat(book, notNullValue()); }
  46. 46. @Test public void deveConterOLivro_javaee7() { Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://localhost:8080/rest-example/resources"); WebTarget path = target.path("books/{id}"); WebTarget bookId = path.resolveTemplate("id", "10"); Builder invocation = bookId.request(); Book book = invocation.get(Book.class); client.close(); assertThat(book, notNullValue()); }
  47. 47. @Test public void deveConterOLivro_javaee7() { Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://localhost:8080/rest-example/resources"); WebTarget path = target.path("books/{id}"); WebTarget bookId = path.resolveTemplate("id", "10"); Builder invocation = bookId.request(); Book book = invocation.get(Book.class); client.close(); assertThat(book, notNullValue()); }
  48. 48. ...“um pouco” mais fluente...
  49. 49. @Test public void deveConterOLivro_javaee7() { Client client = ClientBuilder.newClient(); Book book = client.target("http://localhost:8080/rest-example/resources") .path("books/{id}") .resolveTemplate("id", "10") .request() .get(Book.class); client.close(); assertThat(book, notNullValue()); }
  50. 50. ...@Delete...
  51. 51. @Test public void deletarOLivro_javaee7() { Client client = ClientBuilder.newClient(); Response res = client.target("http://localhost:8080/rest-example/resources") .path("books/{id}") .resolveTemplate("id", "10") .request() .delete(); response.close(); client.close(); assertEquals(Status.OK.getStatusCode(), res.getStatus()); }
  52. 52. @Test public void deletarOLivro_javaee7() { Client client = ClientBuilder.newClient(); Response res = client.target("http://localhost:8080/rest-example/resources") .path("books/{id}") .resolveTemplate("id", "10") .request() .delete(); response.close(); client.close(); assertEquals(Status.OK.getStatusCode(), res.getStatus()); }
  53. 53. @Test public void deletarOLivro_javaee7() { Client client = ClientBuilder.newClient(); Response res = client.target("http://localhost:8080/rest-example/resources") .path("books/{id}") .resolveTemplate("id", "10") .request() .delete(); response.close(); client.close(); assertEquals(Status.OK.getStatusCode(), res.getStatus()); }
  54. 54. @Test public void deletarOLivro_javaee7() { Client client = ClientBuilder.newClient(); Response res = client.target("http://localhost:8080/rest-example/resources") .path("books/{id}") .resolveTemplate("id", "10") .request() .delete(); response.close(); client.close(); assertEquals(Status.OK.getStatusCode(), res.getStatus()); }
  55. 55. ...@Post...
  56. 56. @Test public void inserirOLivro_javaee7() { Client client = ClientBuilder.newClient(); Book book = new Book(1, "Android", "Direto das trincheiras"); Response response = client.target("http://localhost:8080/rest-example/resources") .path("books") .request(MediaType.APPLICATION_JSON) .post(Entity.entity(book, MediaType.APPLICATION_JSON)); response.close(); client.close(); assertEquals(Status.OK.getStatusCode(), response.getStatus()); }
  57. 57. @Test public void inserirOLivro_javaee7() { Client client = ClientBuilder.newClient(); Book book = new Book(1, "Android", "Direto das trincheiras"); Response response = client.target("http://localhost:8080/rest-example/resources") .path("books") .request(MediaType.APPLICATION_JSON) .post(Entity.entity(book, MediaType.APPLICATION_JSON)); response.close(); client.close(); assertEquals(Status.OK.getStatusCode(), response.getStatus()); }
  58. 58. @Test public void inserirOLivro_javaee7() { Client client = ClientBuilder.newClient(); Book book = new Book(1, "Android", "Direto das trincheiras"); Response response = client.target("http://localhost:8080/rest-example/resources") .path("books") .request(MediaType.APPLICATION_JSON) .post(Entity.entity(book, MediaType.APPLICATION_JSON)); response.close(); client.close(); assertEquals(Status.OK.getStatusCode(), response.getStatus()); }
  59. 59. @Test public void inserirOLivro_javaee7() { Client client = ClientBuilder.newClient(); Book book = new Book(1, "Android", "Direto das trincheiras"); Response response = client.target("http://localhost:8080/rest-example/resources") .path("books") .request(MediaType.APPLICATION_JSON) .post(Entity.entity(book, MediaType.APPLICATION_JSON)); response.close(); client.close(); assertEquals(Status.OK.getStatusCode(), response.getStatus()); }
  60. 60. Como configurar Filters e Interceptors?
  61. 61. @Test public void inserirOLivroComFiltroDeLog() { Client client = ClientBuilder.newClient(); client.register(MyLoggingFilter.class); Book book = new Book(1, "Android", "Direto das trincheiras"); Response response = client.target("http://localhost:8080/rest-example/resources") .path("books") .register(MyEntityInterceptor.class) .request(MediaType.APPLICATION_JSON) .post(Entity.entity(book, MediaType.APPLICATION_JSON)); response.close(); client.close(); assertEquals(Status.OK.getStatusCode(), response.getStatus()); }
  62. 62. @Test public void inserirOLivroComFiltroDeLog() { Client client = ClientBuilder.newClient(); client.register(MyLoggingFilter.class); Book book = new Book(1, "Android", "Direto das trincheiras"); Response response = client.target("http://localhost:8080/rest-example/resources") .path("books") .register(MyEntityInterceptor.class) .request(MediaType.APPLICATION_JSON) .post(Entity.entity(book, MediaType.APPLICATION_JSON)); response.close(); client.close(); assertEquals(Status.OK.getStatusCode(), response.getStatus()); }
  63. 63. @Test public void inserirOLivroComFiltroDeLog() { Client client = ClientBuilder.newClient(); client.register(MyLoggingFilter.class); Book book = new Book(1, "Android", "Direto das trincheiras"); Response response = client.target("http://localhost:8080/rest-example/resources") .path("books") .register(MyEntityInterceptor.class) .request(MediaType.APPLICATION_JSON) .post(Entity.entity(book, MediaType.APPLICATION_JSON)); response.close(); client.close(); assertEquals(Status.OK.getStatusCode(), response.getStatus()); }
  64. 64. @Test public void inserirOLivroComFiltroDeLog() { Client client = ClientBuilder.newClient(); client.register(MyLoggingFilter.class); Book book = new Book(1, "Android", "Direto das trincheiras"); Response response = client.target("http://localhost:8080/rest-example/resources") .path("books") .register(MyEntityInterceptor.class) .request(MediaType.APPLICATION_JSON) .post(Entity.entity(book, MediaType.APPLICATION_JSON)); response.close(); client.close(); assertEquals(Status.OK.getStatusCode(), response.getStatus()); }
  65. 65. Asynchronous Processing
  66. 66. Que tal uma chamada assíncrona?
  67. 67. @Path("books") public class BookResource { @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id) throws InterruptedException { Thread.sleep(5000L); return Response.ok(readObject(id)).build(); } }
  68. 68. @Path("books") public class BookResource { @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id) throws InterruptedException { Thread.sleep(5000L); return Response.ok(readObject(id)).build(); } } Simulando um processamento pesado.
  69. 69. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); System.out.println("Cancelado: " + asyncResponse.isCancelled()); Thread.sleep(2000L); System.out.println("Finalizado: " + asyncResponse.isDone()); Thread.sleep(5000L); System.out.println("Finalizado: " + asyncResponse.isDone()); assertThat(asyncResponse.get(), notNullValue()); }
  70. 70. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); System.out.println("Cancelado: " + asyncResponse.isCancelled()); Thread.sleep(2000L); System.out.println("Finalizado: " + asyncResponse.isDone()); Thread.sleep(5000L); System.out.println("Finalizado: " + asyncResponse.isDone()); assertThat(asyncResponse.get(), notNullValue()); }
  71. 71. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); System.out.println("Cancelado: " + asyncResponse.isCancelled()); Thread.sleep(2000L); System.out.println("Finalizado: " + asyncResponse.isDone()); Thread.sleep(5000L); System.out.println("Finalizado: " + asyncResponse.isDone()); assertThat(asyncResponse.get(), notNullValue()); }
  72. 72. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); System.out.println("Cancelado: " + asyncResponse.isCancelled()); Thread.sleep(2000L); System.out.println("Finalizado: " + asyncResponse.isDone()); Thread.sleep(5000L); System.out.println("Finalizado: " + asyncResponse.isDone()); assertThat(asyncResponse.get(), notNullValue()); }
  73. 73. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); System.out.println("Cancelado: " + asyncResponse.isCancelled()); // false Thread.sleep(2000L); System.out.println("Finalizado: " + asyncResponse.isDone()); Thread.sleep(5000L); System.out.println("Finalizado: " + asyncResponse.isDone()); assertThat(asyncResponse.get(), notNullValue()); }
  74. 74. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); System.out.println("Cancelado: " + asyncResponse.isCancelled()); // false Thread.sleep(2000L); System.out.println("Finalizado: " + asyncResponse.isDone()); Thread.sleep(5000L); System.out.println("Finalizado: " + asyncResponse.isDone()); assertThat(asyncResponse.get(), notNullValue()); }
  75. 75. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); System.out.println("Cancelado: " + asyncResponse.isCancelled()); // false Thread.sleep(2000L); System.out.println("Finalizado: " + asyncResponse.isDone()); Thread.sleep(5000L); System.out.println("Finalizado: " + asyncResponse.isDone()); assertThat(asyncResponse.get(), notNullValue()); }
  76. 76. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); System.out.println("Cancelado: " + asyncResponse.isCancelled()); // false Thread.sleep(2000L); System.out.println("Finalizado: " + asyncResponse.isDone()); // false Thread.sleep(5000L); System.out.println("Finalizado: " + asyncResponse.isDone()); assertThat(asyncResponse.get(), notNullValue()); }
  77. 77. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); System.out.println("Cancelado: " + asyncResponse.isCancelled()); // false Thread.sleep(2000L); System.out.println("Finalizado: " + asyncResponse.isDone()); // false Thread.sleep(5000L); System.out.println("Finalizado: " + asyncResponse.isDone()); assertThat(asyncResponse.get(), notNullValue()); }
  78. 78. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); System.out.println("Cancelado: " + asyncResponse.isCancelled()); // false Thread.sleep(2000L); System.out.println("Finalizado: " + asyncResponse.isDone()); // false Thread.sleep(5000L); System.out.println("Finalizado: " + asyncResponse.isDone()); assertThat(asyncResponse.get(), notNullValue()); }
  79. 79. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); System.out.println("Cancelado: " + asyncResponse.isCancelled()); // false Thread.sleep(2000L); System.out.println("Finalizado: " + asyncResponse.isDone()); // false Thread.sleep(5000L); System.out.println("Finalizado: " + asyncResponse.isDone()); // true assertThat(asyncResponse.get(), notNullValue()); }
  80. 80. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); System.out.println("Cancelado: " + asyncResponse.isCancelled()); // false Thread.sleep(2000L); System.out.println("Finalizado: " + asyncResponse.isDone()); // false Thread.sleep(5000L); System.out.println("Finalizado: " + asyncResponse.isDone()); // true assertThat(asyncResponse.get(), notNullValue()); }
  81. 81. Timeout no método get() JSR 236 - Concurrency Utilities for JavaTM EE
  82. 82. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); assertThat(asyncResponse.get(20L, TimeUnit.SECONDS), notNullValue()); }
  83. 83. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); assertThat(asyncResponse.get(20L, TimeUnit.SECONDS), notNullValue()); }
  84. 84. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); assertThat(asyncResponse.get(2L, TimeUnit.SECONDS), notNullValue()); }
  85. 85. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); Future<Book> asyncResponse = target.request().async().get(Book.class); assertThat(asyncResponse.get(2L, TimeUnit.SECONDS), notNullValue()); }
  86. 86. Posso enviar um InvocationCallback?
  87. 87. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); target.request().async().get(new InvocationCallback<Book>() { public void completed(Book book) { assertThat(book, notNullValue()); } public void failed(Throwable throwable) { fail(); } }); }
  88. 88. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); target.request().async().get(new InvocationCallback<Book>() { public void completed(Book book) { assertThat(book, notNullValue()); } public void failed(Throwable throwable) { fail(); } }); }
  89. 89. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); target.request().async().get(new InvocationCallback<Book>() { public void completed(Book book) { assertThat(book, notNullValue()); } public void failed(Throwable throwable) { fail(); } }); }
  90. 90. @Test public void buscaOLivroDeFormaAssincrona() { WebTarget target = ClientBuilder.newClient() .target("http://localhost:8080/rest-example/resources") .path("books/10"); target.request().async().get(new InvocationCallback<Book>() { public void completed(Book book) { assertThat(book, notNullValue()); } public void failed(Throwable throwable) { fail(); } }); }
  91. 91. Assíncrono no servidor... ...se você quiser!
  92. 92. Primeiro, sem EJB...
  93. 93. @Path("async/books") public class AsyncBookResource { @GET @Path("/") @Produces(MediaType.APPLICATION_JSON) public void longRunningOperation(@Suspended final AsyncResponse asyncResponse) { Runnable command = new Runnable() { public void run() { Thread.sleep(10000L); asyncResponse.resume(new Book()); } }; Executors.newSingleThreadExecutor().execute(command); } }
  94. 94. @Path("async/books") public class AsyncBookResource { @GET @Path("/") @Produces(MediaType.APPLICATION_JSON) public void longRunningOperation(@Suspended final AsyncResponse asyncResponse) { Runnable command = new Runnable() { public void run() { Thread.sleep(10000L); asyncResponse.resume(new Book()); } }; Executors.newSingleThreadExecutor().execute(command); } }
  95. 95. @Path("async/books") public class AsyncBookResource { @GET @Path("/") @Produces(MediaType.APPLICATION_JSON) public void longRunningOperation(@Suspended final AsyncResponse asyncResponse) { Runnable command = new Runnable() { public void run() { Thread.sleep(10000L); asyncResponse.resume(new Book()); } }; Executors.newSingleThreadExecutor().execute(command); } }
  96. 96. @Path("async/books") public class AsyncBookResource { @GET @Path("/") @Produces(MediaType.APPLICATION_JSON) public void longRunningOperation(@Suspended final AsyncResponse asyncResponse) { Runnable command = new Runnable() { public void run() { Thread.sleep(10000L); asyncResponse.resume(new Book()); } }; Executors.newSingleThreadExecutor().execute(command); // JSR 236 } }
  97. 97. @Path("async/books") public class AsyncBookResource { @GET @Path("/") @Produces(MediaType.APPLICATION_JSON) public void longRunningOperation(@Suspended final AsyncResponse asyncResponse) { Runnable command = new Runnable() { public void run() { Thread.sleep(10000L); asyncResponse.resume(new Book()); } }; Executors.newSingleThreadExecutor().execute(command); // JSR 236 } }
  98. 98. @Path("async/books") public class AsyncBookResource { @GET @Path("/") @Produces(MediaType.APPLICATION_JSON) public void longRunningOperation(@Suspended final AsyncResponse asyncResponse) { Runnable command = new Runnable() { public void run() { Thread.sleep(10000L); asyncResponse.resume(new Book()); } }; Executors.newSingleThreadExecutor().execute(command); // JSR 236 } }
  99. 99. E se for com EJB?
  100. 100. @Stateless @Path("async/books") public class AsyncBookResource { @GET @Path("/") @Asynchronous @Produces(MediaType.APPLICATION_JSON) public void longRunningOperation(@Suspended final AsyncResponse asyncResponse) { Thread.sleep(10000L); asyncResponse.resume(new Book()); } } EJB 3.1 (Java EE 6)
  101. 101. @Stateless @Path("async/books") public class AsyncBookResource { @GET @Path("/") @Asynchronous @Produces(MediaType.APPLICATION_JSON) public void longRunningOperation(@Suspended final AsyncResponse asyncResponse) { Thread.sleep(10000L); asyncResponse.resume(new Book()); } }
  102. 102. @Stateless @Path("async/books") public class AsyncBookResource { @GET @Path("/") @Asynchronous @Produces(MediaType.APPLICATION_JSON) public void longRunningOperation(@Suspended final AsyncResponse asyncResponse) { Thread.sleep(10000L); asyncResponse.resume(new Book()); } }
  103. 103. @Stateless @Path("async/books") public class AsyncBookResource { @GET @Path("/") @Asynchronous @Produces(MediaType.APPLICATION_JSON) public void longRunningOperation(@Suspended final AsyncResponse asyncResponse) { Thread.sleep(10000L); asyncResponse.resume(new Book()); } }
  104. 104. Filters and Interceptors
  105. 105. O que são os filters?
  106. 106. ClientRequestFilter ClientResponseFilter
  107. 107. @Provider public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  108. 108. @Provider public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  109. 109. @Provider public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  110. 110. @Provider public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  111. 111. @Provider public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  112. 112. ContainerRequestFilter ContainerResponserFilter
  113. 113. @Provider class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  114. 114. @Provider class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  115. 115. @Provider class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  116. 116. @Provider class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  117. 117. @Provider class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  118. 118. O que são os interceptors?
  119. 119. ReaderInterceptor WriterInterceptor
  120. 120. Descompactando a requisição
  121. 121. @Provider public class GzipReaderInterceptor implements ReaderInterceptor { Object aroundReadFrom(ReaderInterceptorContext ctx) ... { if (isGzipped(ctx)) { InputStream old = ctx.getInputStream(); ctx.setInputStream(new GZIPInputStream(old)); try { return ctx.proceed(); } finally { ctx.setInputStream(old); } } else { return ctx.proceed(); } } }
  122. 122. @Provider public class GzipReaderInterceptor implements ReaderInterceptor { Object aroundReadFrom(ReaderInterceptorContext ctx) ... { if (isGzipped(ctx)) { InputStream old = ctx.getInputStream(); ctx.setInputStream(new GZIPInputStream(old)); try { return ctx.proceed(); } finally { ctx.setInputStream(old); } } else { return ctx.proceed(); } } }
  123. 123. @Provider public class GzipReaderInterceptor implements ReaderInterceptor { Object aroundReadFrom(ReaderInterceptorContext ctx) ... { if (isGzipped(ctx)) { InputStream old = ctx.getInputStream(); ctx.setInputStream(new GZIPInputStream(old)); try { return ctx.proceed(); } finally { ctx.setInputStream(old); } } else { return ctx.proceed(); } } }
  124. 124. @Provider public class GzipReaderInterceptor implements ReaderInterceptor { Object aroundReadFrom(ReaderInterceptorContext ctx) ... { if (isGzipped(ctx)) { InputStream old = ctx.getInputStream(); ctx.setInputStream(new GZIPInputStream(old)); try { return ctx.proceed(); } finally { ctx.setInputStream(old); } } else { return ctx.proceed(); } } }
  125. 125. Compactando a resposta
  126. 126. @Provider public class GzipWriteInterceptor implements WriteInterceptor { void aroundWriteTo(WriterInterceptorContext ctx) ... { OutputStream old = ctx.getOutputStream(); GZIPOutputStream gzipOutputStream = new GZIPOutputStream(old); ctx.setOutputStream(gzipOutputStream); updateHeaders(ctx); try { ctx.proceed(); } finally { gzipOutputStream.finish(); ctx.setOutputStream(old); } } }
  127. 127. @Provider public class GzipWriteInterceptor implements WriteInterceptor { void aroundWriteTo(WriterInterceptorContext ctx) ... { OutputStream old = ctx.getOutputStream(); GZIPOutputStream gzipOutputStream = new GZIPOutputStream(old); ctx.setOutputStream(gzipOutputStream); updateHeaders(ctx); try { ctx.proceed(); } finally { gzipOutputStream.finish(); ctx.setOutputStream(old); } } }
  128. 128. @Provider public class GzipWriteInterceptor implements WriteInterceptor { void aroundWriteTo(WriterInterceptorContext ctx) ... { OutputStream old = ctx.getOutputStream(); GZIPOutputStream gzipOutputStream = new GZIPOutputStream(old); ctx.setOutputStream(gzipOutputStream); updateHeaders(ctx); try { ctx.proceed(); } finally { gzipOutputStream.finish(); ctx.setOutputStream(old); } } }
  129. 129. @Provider public class GzipWriteInterceptor implements WriteInterceptor { void aroundWriteTo(WriterInterceptorContext ctx) ... { OutputStream old = ctx.getOutputStream(); GZIPOutputStream gzipOutputStream = new GZIPOutputStream(old); ctx.setOutputStream(gzipOutputStream); updateHeaders(ctx); try { ctx.proceed(); } finally { gzipOutputStream.finish(); ctx.setOutputStream(old); } } }
  130. 130. Mas, qual é a diferença mesmo?
  131. 131. Filters: Acesso ao contexto do request/response.
  132. 132. Exemplo de Filters Logar origem do request. Verificar qual o método http utilizado. Qual a URI.
  133. 133. Interceptors: Acesso ao contexto da mensagem.
  134. 134. Exemplo de Interceptors Compactar o conteúdo da mensagem a ser enviada. Descompactar o conteúdo da mensagem a ser lida.
  135. 135. Posso logar minhas requisições antes de chegar ao método?
  136. 136. @PreMatching
  137. 137. @Provider @PreMatching public class HttpPreMatchingFilter implements ContainerRequestFilter { public void filter(ContainerRequestContext requestContext) throws IOException { ... } }
  138. 138. @Provider @PreMatching public class HttpPreMatchingFilter implements ContainerRequestFilter { public void filter(ContainerRequestContext requestContext) throws IOException { ... } }
  139. 139. @Provider @PreMatching public class HttpPreMatchingFilter implements ContainerRequestFilter { public void filter(ContainerRequestContext requestContext) throws IOException { ... } }
  140. 140. Mas se eu quiser logar um método específico, é possível?
  141. 141. @NameBinding
  142. 142. @NameBinding @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(value = RetentionPolicy.RUNTIME) public @interface Logged {} Similar aos qualificadores do CDI
  143. 143. @Provider @Logged public class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { ... }
  144. 144. @Path("/") public class MyResourceClass { @GET @Logged @Path("{name}") @Produces("text/plain") public String hello(@PathParam("name") String name) { return "Hello " + name; } }
  145. 145. E a ordem? Posso definir?
  146. 146. @Priority
  147. 147. @Provider @Authenticated @Priority(Priorities.AUTHENTICATION) public class AuthenticationFilter implements ContainerRequestFilter{ ... }
  148. 148. Modifier and Type Constant Field Value public static final int AUTHENTICATION 1000 public static final int AUTHORIZATION 2000 public static final int ENTITY_CODER 3000 public static final int HEADER_DECORATOR 4000 public static final int USER 5000 javax.ws.rs.Priorities
  149. 149. Bean Validation JSR-349
  150. 150. Como eu aplico?
  151. 151. public class Book { private Integer id; @NotNull private String name; private String description; private Integer year; private String genero; }
  152. 152. @POST @Consumes(MediaType.APPLICATION_JSON) public Response create(@Valid Book book) { ResponseBuilder rb = Response.ok(createObject(book)); return rb.build(); }
  153. 153. @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@Max(2015) @PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); }
  154. 154. HATEOAS Hipermídia como motor do estado do aplicativo “If the engine of application is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API” (Roy T. Fielding)
  155. 155. Book Purchase Related Books Author Receipt /books/1/author /books/genre/programming /books/1/purchase /books/1/purchase/12/receipt /books/1 Exemplo
  156. 156. Link: <http://gujavasc.org/resources/books/1/purchase>; rel=purchase, … <book> <id>1</id> <year>2013</year> <name>REST in practice</name> <genre>programming</genre> <author>http://gujavasc.org/resources/books/1/author</author> <related>http://gujavasc.org/resources/books/genre/programming</related> </book> Links Transicionais Links Estruturais
  157. 157. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  158. 158. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  159. 159. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  160. 160. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  161. 161. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  162. 162. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  163. 163. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  164. 164. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  165. 165. Integração com Java EE Managed Beans CDI EJB Bean Validation JSON API
  166. 166. OBRIGADO! Daniel Cunha (Soro) - @dvlc_ Ivan Junckes Filho - @ivanjunckes Ricardo Longa - @ricardolonga https://github.com/gujavasc/jaxrs2

×