jsr 339 - java api for restful web services

Post on 16-Jul-2015

153 Views

Category:

Software

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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 uniforme.

Características

Recursos são identificados por um ID;

Sem estado;

Vincule as coisas;

Múltiplas representações;

Interface uniforme.

Interface Uniforme

Verbos HTTP Ação

POST Cria um novo recurso

PUT Atualiza um recurso

DELETE Remove um recurso

GET Retorna um recurso

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

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

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

}

}

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

}

}

@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

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

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

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

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

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

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

JAX-RS 2.0

Final Release em Maio de 2013

Solicitações (JSR 339)

Client API

Asynchronous processing

Filters / Interceptors

Bean Validation

Hypermedia

MVC

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(@PathParam("id") Integer id) {

return Response.ok(readObject(id)).build();

}

}

http://localhost:8080/rest-example/resources/books/10

Como consultávamos?

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

}

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

}

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

}

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

}

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

}

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

}

@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

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

}

E agora com a Client API?

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

}

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

}

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

}

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

}

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

}

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

}

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

}

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

}

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

}

...“um pouco” mais fluente...

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

}

...@Delete...

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

}

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

}

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

}

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

}

...@Post...

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

}

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

}

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

}

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

}

Como configurar Filters e Interceptors?

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

}

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

}

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

}

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

}

AsynchronousProcessing

Que tal uma chamada assíncrona?

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

}

}

@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.

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

}

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

}

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

}

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

}

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

}

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

}

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

}

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

}

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

}

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

}

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

}

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

}

Timeout no método get()JSR 236 - Concurrency Utilities for JavaTM EE

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

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

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

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

Posso enviar um InvocationCallback?

@Testpublic 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();

}

});

}

@Testpublic 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();

}

});

}

@Testpublic 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();

}

});

}

@Testpublic 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();

}

});

}

Assíncrono no servidor......se você quiser!

Primeiro, sem EJB...

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

}

}

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

}

}

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

}

}

@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

}

}

@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

}

}

@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

}

}

E se for com EJB?

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

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

}

}

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

}

}

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

}

}

Filters and Interceptors

O que são os filters?

ClientRequestFilter

ClientResponseFilter

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

}

}

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

}

}

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

}

}

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

}

}

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

}

}

ContainerRequestFilter

ContainerResponserFilter

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

}

}

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

}

}

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

}

}

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

}

}

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

}

}

O que são os interceptors?

ReaderInterceptor

WriterInterceptor

Descompactando a requisição

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

}

}

}

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

}

}

}

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

}

}

}

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

}

}

}

Compactando a resposta

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

}

}

}

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

}

}

}

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

}

}

}

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

}

}

}

Mas, qual é a diferençamesmo?

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 damensagem.

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çõesantes de chegar ao método?

@PreMatching

@Provider@PreMatchingpublic class HttpPreMatchingFilter implements ContainerRequestFilter {

public void filter(ContainerRequestContext requestContext) throws IOException {...

}

}

@Provider@PreMatchingpublic class HttpPreMatchingFilter implements ContainerRequestFilter {

public void filter(ContainerRequestContext requestContext) throws IOException {...

}

}

@Provider@PreMatchingpublic class HttpPreMatchingFilter implements ContainerRequestFilter {

public void filter(ContainerRequestContext requestContext) throws IOException {...

}

}

Mas se eu quiser logar um método específico, é possível?

@NameBinding

@NameBinding@Target({ ElementType.TYPE, ElementType.METHOD })@Retention(value = RetentionPolicy.RUNTIME)public @interface Logged {}

Similar aos qualificadores do

CDI

@Provider @Loggedpublic class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter {

...}

@Path("/")public class MyResourceClass {

@GET@Logged@Path("{name}")@Produces("text/plain")public String hello(@PathParam("name") String name) {

return "Hello " + name;}

}

E a ordem? Posso definir?

@Priority

@Provider@Authenticated@Priority(Priorities.AUTHENTICATION)public class AuthenticationFilter implements ContainerRequestFilter{

...}

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

Bean ValidationJSR-349

Como eu aplico?

public class Book {

private Integer id;

@NotNullprivate String name;

private String description;private Integer year;private String genero;

}

@POST@Consumes(MediaType.APPLICATION_JSON)public Response create(@Valid Book book) {

ResponseBuilder rb = Response.ok(createObject(book));return rb.build();

}

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

}

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)

Book Purchase

Related Books

Author

Receipt

/books/1/author

/books/genre/programming

/books/1/purchase

/books/1/purchase/12/receipt

/books/1

Exemplo

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

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

}

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

}

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

}

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

}

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

}

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

}

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

}

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

}

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/gujavasc/jaxrs2

top related