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());
}
Asynchronous
Processing
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
@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());
}
@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());
}
@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());
}
@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());
}
Posso enviar um InvocationCallback?
@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();
}
});
}
@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();
}
});
}
@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();
}
});
}
@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();
}
});
}
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ç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(ContainerRequestContext requestContext) throws IOException {
...
}
}
@Provider
@PreMatching
public class HttpPreMatchingFilter implements ContainerRequestFilter {
public void filter(ContainerRequestContext requestContext) throws IOException {
...
}
}
@Provider
@PreMatching
public 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 @Logged
public 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 Validation
JSR-349
Como eu aplico?
public class Book {
private Integer id;
@NotNull
private 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

JSR 339 - Java API for RESTful Web Services

  • 1.
    JSR 339 Java APIfor RESTful Web Services
  • 2.
    GujavaSC / Adopta JSR Membros do GujavaSC Participação Adopt a JSR Grupo de estudos Artigos Palestras
  • 3.
    O que éREST?
  • 4.
    É um estiloarquitetural…
  • 5.
    Estilo arquitetural??? É umestilo arquitetural…
  • 6.
  • 7.
  • 8.
    Características Recursos são identificadospor um ID; Sem estado; Vincule as coisas; Múltiplas representações; Interface uniforme.
  • 9.
    Características Recursos são identificadospor um ID; Sem estado; Vincule as coisas; Múltiplas representações; Interface uniforme.
  • 10.
    Interface Uniforme Verbos HTTPAção POST Cria um novo recurso PUT Atualiza um recurso DELETE Remove um recurso GET Retorna um recurso
  • 11.
    JAX-RS 1.x Final Releaseem 2008 Objetivos Baseado em POJO Centralizado em HTTP Independência de formato Independência de container Inclusão no Java EE 6
  • 12.
    Exemplo JAX-RS 1.0 @Path("books") publicclass 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.
    Exemplo JAX-RS 1.0 http://localhost:8080/rest-example/resources/books/year/2011?name=Book1 @Path("books") publicclass 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.
    Exemplo JAX-RS 1.0 http://localhost:8080/rest-example/resources/books/year/2011?name=Book1 @Path("books") publicclass 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.
    @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.
    Exemplo JAX-RS 1.0 @Path("books") publicclass 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.
    Exemplo JAX-RS 1.0 @Path("books") publicclass 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.
    Exemplo JAX-RS 1.0 @Path("books") publicclass 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.
    Exemplo JAX-RS 1.0 @Path("books") publicclass 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.
    Exemplo JAX-RS 1.0 @Path("books") publicclass 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.
    Exemplo JAX-RS 1.0 @Path("books") publicclass 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.
    JAX-RS 2.0 Final Releaseem Maio de 2013 Solicitações (JSR 339) Client API Asynchronous processing Filters / Interceptors Bean Validation Hypermedia MVC
  • 23.
  • 24.
    Client API Baseada naAPI do Jersey (versão 1.x); Consumir serviços criados em qualquer linguagem.
  • 25.
    Qual é orecurso?
  • 26.
  • 27.
  • 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.
  • 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.
    @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.
    @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.
    @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.
    @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.
    @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.
    @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.
    @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.
    E agora coma Client API?
  • 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.
    @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.
    @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.
    @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.
    @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.
    @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.
    @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.
    @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.
    @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.
  • 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.
  • 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.
    @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.
    @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.
    @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.
  • 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.
    @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.
    @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.
    @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.
  • 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.
    @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.
    @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.
    @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.
  • 66.
    Que tal umachamada assíncrona?
  • 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.
    @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.
    @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.
    @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.
    @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.
    @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.
    @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.
    @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.
    @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.
    @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.
    @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.
    @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.
    @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.
    @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.
    Timeout no métodoget() JSR 236 - Concurrency Utilities for JavaTM EE
  • 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.
    @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.
    @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.
    @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.
    Posso enviar umInvocationCallback?
  • 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.
    @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.
    @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.
    @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.
  • 92.
  • 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.
    @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.
    @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.
    @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.
    @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.
    @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.
    E se forcom EJB?
  • 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.
    @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.
    @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.
    @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.
  • 105.
    O que sãoos filters?
  • 106.
  • 107.
    @Provider public class LoggingFilterimplements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  • 108.
    @Provider public class LoggingFilterimplements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  • 109.
    @Provider public class LoggingFilterimplements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  • 110.
    @Provider public class LoggingFilterimplements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  • 111.
    @Provider public class LoggingFilterimplements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  • 112.
  • 113.
    @Provider class LoggingFilter implementsContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  • 114.
    @Provider class LoggingFilter implementsContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  • 115.
    @Provider class LoggingFilter implementsContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  • 116.
    @Provider class LoggingFilter implementsContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  • 117.
    @Provider class LoggingFilter implementsContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  • 118.
    O que sãoos interceptors?
  • 119.
  • 120.
  • 121.
    @Provider public class GzipReaderInterceptorimplements 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.
    @Provider public class GzipReaderInterceptorimplements 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.
    @Provider public class GzipReaderInterceptorimplements 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.
    @Provider public class GzipReaderInterceptorimplements 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.
  • 126.
    @Provider public class GzipWriteInterceptorimplements 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.
    @Provider public class GzipWriteInterceptorimplements 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.
    @Provider public class GzipWriteInterceptorimplements 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.
    @Provider public class GzipWriteInterceptorimplements 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.
    Mas, qual éa diferença mesmo?
  • 131.
    Filters: Acesso aocontexto do request/response.
  • 132.
    Exemplo de Filters Logarorigem do request. Verificar qual o método http utilizado. Qual a URI.
  • 133.
    Interceptors: Acesso aocontexto da mensagem.
  • 134.
    Exemplo de Interceptors Compactaro conteúdo da mensagem a ser enviada. Descompactar o conteúdo da mensagem a ser lida.
  • 135.
    Posso logar minhasrequisições antes de chegar ao método?
  • 136.
  • 137.
    @Provider @PreMatching public class HttpPreMatchingFilterimplements ContainerRequestFilter { public void filter(ContainerRequestContext requestContext) throws IOException { ... } }
  • 138.
    @Provider @PreMatching public class HttpPreMatchingFilterimplements ContainerRequestFilter { public void filter(ContainerRequestContext requestContext) throws IOException { ... } }
  • 139.
    @Provider @PreMatching public class HttpPreMatchingFilterimplements ContainerRequestFilter { public void filter(ContainerRequestContext requestContext) throws IOException { ... } }
  • 140.
    Mas se euquiser logar um método específico, é possível?
  • 141.
  • 142.
    @NameBinding @Target({ ElementType.TYPE, ElementType.METHOD}) @Retention(value = RetentionPolicy.RUNTIME) public @interface Logged {} Similar aos qualificadores do CDI
  • 143.
    @Provider @Logged public classLoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { ... }
  • 144.
    @Path("/") public class MyResourceClass{ @GET @Logged @Path("{name}") @Produces("text/plain") public String hello(@PathParam("name") String name) { return "Hello " + name; } }
  • 145.
    E a ordem?Posso definir?
  • 146.
  • 147.
  • 148.
    Modifier and TypeConstant 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.
  • 150.
  • 151.
    public class Book{ private Integer id; @NotNull private String name; private String description; private Integer year; private String genero; }
  • 152.
    @POST @Consumes(MediaType.APPLICATION_JSON) public Response create(@ValidBook book) { ResponseBuilder rb = Response.ok(createObject(book)); return rb.build(); }
  • 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.
    HATEOAS Hipermídia como motordo 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.
  • 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.
    Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Responseread(@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.
    Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Responseread(@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.
    Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Responseread(@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.
    Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Responseread(@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.
    Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Responseread(@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.
    Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Responseread(@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.
    Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Responseread(@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.
    Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Responseread(@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.
    Integração com JavaEE Managed Beans CDI EJB Bean Validation JSON API
  • 166.
    OBRIGADO! Daniel Cunha (Soro)- @dvlc_ Ivan Junckes Filho - @ivanjunckes Ricardo Longa - @ricardolonga https://github.com/gujavasc/jaxrs2