SlideShare una empresa de Scribd logo
1 de 166
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

Más contenido relacionado

La actualidad más candente

UKOUG Tech14 - Getting Started With JSON in the Database
UKOUG Tech14 - Getting Started With JSON in the DatabaseUKOUG Tech14 - Getting Started With JSON in the Database
UKOUG Tech14 - Getting Started With JSON in the DatabaseMarco Gralike
 
A Semantic Description Language for RESTful Data Services to Combat Semaphobia
A Semantic Description Language for RESTful Data Services to Combat SemaphobiaA Semantic Description Language for RESTful Data Services to Combat Semaphobia
A Semantic Description Language for RESTful Data Services to Combat SemaphobiaMarkus Lanthaler
 
Aligning Web Services with the Semantic Web to Create a Global Read-Write Gra...
Aligning Web Services with the Semantic Web to Create a Global Read-Write Gra...Aligning Web Services with the Semantic Web to Create a Global Read-Write Gra...
Aligning Web Services with the Semantic Web to Create a Global Read-Write Gra...Markus Lanthaler
 
GraphQL & Relay - 串起前後端世界的橋樑
GraphQL & Relay - 串起前後端世界的橋樑GraphQL & Relay - 串起前後端世界的橋樑
GraphQL & Relay - 串起前後端世界的橋樑Pokai Chang
 
Starting with JSON Path Expressions in Oracle 12.1.0.2
Starting with JSON Path Expressions in Oracle 12.1.0.2Starting with JSON Path Expressions in Oracle 12.1.0.2
Starting with JSON Path Expressions in Oracle 12.1.0.2Marco Gralike
 
Oracle Database - JSON and the In-Memory Database
Oracle Database - JSON and the In-Memory DatabaseOracle Database - JSON and the In-Memory Database
Oracle Database - JSON and the In-Memory DatabaseMarco Gralike
 
JSON(JavaScript Object Notation)
JSON(JavaScript Object Notation)JSON(JavaScript Object Notation)
JSON(JavaScript Object Notation)Raghu nath
 
java API for XML DOM
java API for XML DOMjava API for XML DOM
java API for XML DOMSurinder Kaur
 
So various polymorphism in Scala
So various polymorphism in ScalaSo various polymorphism in Scala
So various polymorphism in Scalab0ris_1
 
Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...
Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...
Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...Codemotion
 
Mail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - ItalyMail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - ItalyYahoo
 
Comparing JSON Libraries - July 19 2011
Comparing JSON Libraries - July 19 2011Comparing JSON Libraries - July 19 2011
Comparing JSON Libraries - July 19 2011sullis
 

La actualidad más candente (18)

UKOUG Tech14 - Getting Started With JSON in the Database
UKOUG Tech14 - Getting Started With JSON in the DatabaseUKOUG Tech14 - Getting Started With JSON in the Database
UKOUG Tech14 - Getting Started With JSON in the Database
 
A Semantic Description Language for RESTful Data Services to Combat Semaphobia
A Semantic Description Language for RESTful Data Services to Combat SemaphobiaA Semantic Description Language for RESTful Data Services to Combat Semaphobia
A Semantic Description Language for RESTful Data Services to Combat Semaphobia
 
Aligning Web Services with the Semantic Web to Create a Global Read-Write Gra...
Aligning Web Services with the Semantic Web to Create a Global Read-Write Gra...Aligning Web Services with the Semantic Web to Create a Global Read-Write Gra...
Aligning Web Services with the Semantic Web to Create a Global Read-Write Gra...
 
Json at work overview and ecosystem-v2.0
Json at work   overview and ecosystem-v2.0Json at work   overview and ecosystem-v2.0
Json at work overview and ecosystem-v2.0
 
GraphQL & Relay - 串起前後端世界的橋樑
GraphQL & Relay - 串起前後端世界的橋樑GraphQL & Relay - 串起前後端世界的橋樑
GraphQL & Relay - 串起前後端世界的橋樑
 
JSON
JSONJSON
JSON
 
Starting with JSON Path Expressions in Oracle 12.1.0.2
Starting with JSON Path Expressions in Oracle 12.1.0.2Starting with JSON Path Expressions in Oracle 12.1.0.2
Starting with JSON Path Expressions in Oracle 12.1.0.2
 
Oracle Database - JSON and the In-Memory Database
Oracle Database - JSON and the In-Memory DatabaseOracle Database - JSON and the In-Memory Database
Oracle Database - JSON and the In-Memory Database
 
JSON(JavaScript Object Notation)
JSON(JavaScript Object Notation)JSON(JavaScript Object Notation)
JSON(JavaScript Object Notation)
 
CouchDB-Lucene
CouchDB-LuceneCouchDB-Lucene
CouchDB-Lucene
 
java API for XML DOM
java API for XML DOMjava API for XML DOM
java API for XML DOM
 
Advanced Json
Advanced JsonAdvanced Json
Advanced Json
 
Xml
XmlXml
Xml
 
So various polymorphism in Scala
So various polymorphism in ScalaSo various polymorphism in Scala
So various polymorphism in Scala
 
Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...
Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...
Developing and maintaining a Java GraphQL back-end: The less obvious - Bojan ...
 
Mail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - ItalyMail OnLine Android Application at DroidCon - Turin - Italy
Mail OnLine Android Application at DroidCon - Turin - Italy
 
Comparing JSON Libraries - July 19 2011
Comparing JSON Libraries - July 19 2011Comparing JSON Libraries - July 19 2011
Comparing JSON Libraries - July 19 2011
 
Xcap
XcapXcap
Xcap
 

Similar a JSR 339 - Java API for RESTful Web Services

Developing RESTful WebServices using Jersey
Developing RESTful WebServices using JerseyDeveloping RESTful WebServices using Jersey
Developing RESTful WebServices using Jerseyb_kathir
 
JSUG - RESTful Web Services by Florian Motlik
JSUG - RESTful Web Services by Florian MotlikJSUG - RESTful Web Services by Florian Motlik
JSUG - RESTful Web Services by Florian MotlikChristoph Pickl
 
Link.javaLink.javapackage com.bookstore.domain.model;import .docx
Link.javaLink.javapackage com.bookstore.domain.model;import .docxLink.javaLink.javapackage com.bookstore.domain.model;import .docx
Link.javaLink.javapackage com.bookstore.domain.model;import .docxSHIVA101531
 
SAStrutsから読み取るFWの進化
SAStrutsから読み取るFWの進化SAStrutsから読み取るFWの進化
SAStrutsから読み取るFWの進化teeaki
 
RESTful Web Services with Jersey
RESTful Web Services with JerseyRESTful Web Services with Jersey
RESTful Web Services with JerseyScott Leberknight
 
Making Java REST with JAX-RS 2.0
Making Java REST with JAX-RS 2.0Making Java REST with JAX-RS 2.0
Making Java REST with JAX-RS 2.0Dmytro Chyzhykov
 
Overview of GraphQL & Clients
Overview of GraphQL & ClientsOverview of GraphQL & Clients
Overview of GraphQL & ClientsPokai Chang
 
Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Andres Almiray
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreStormpath
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreNate Barbettini
 
03 form-data
03 form-data03 form-data
03 form-datasnopteck
 
Querydsl fin jug - june 2012
Querydsl   fin jug - june 2012Querydsl   fin jug - june 2012
Querydsl fin jug - june 2012Timo Westkämper
 
Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Sven Efftinge
 
Using Java to implement RESTful Web Services: JAX-RS
Using Java to implement RESTful Web Services: JAX-RSUsing Java to implement RESTful Web Services: JAX-RS
Using Java to implement RESTful Web Services: JAX-RSKatrien Verbert
 
PigSPARQL: A SPARQL Query Processing Baseline for Big Data
PigSPARQL: A SPARQL Query Processing Baseline for Big DataPigSPARQL: A SPARQL Query Processing Baseline for Big Data
PigSPARQL: A SPARQL Query Processing Baseline for Big DataAlexander Schätzle
 
Building Restful Web Services with Java
Building Restful Web Services with JavaBuilding Restful Web Services with Java
Building Restful Web Services with JavaVassil Popovski
 
Objects, Testing, and Responsibility
Objects, Testing, and ResponsibilityObjects, Testing, and Responsibility
Objects, Testing, and Responsibilitymachuga
 

Similar a JSR 339 - Java API for RESTful Web Services (20)

JOOQ and Flyway
JOOQ and FlywayJOOQ and Flyway
JOOQ and Flyway
 
Developing RESTful WebServices using Jersey
Developing RESTful WebServices using JerseyDeveloping RESTful WebServices using Jersey
Developing RESTful WebServices using Jersey
 
JSUG - RESTful Web Services by Florian Motlik
JSUG - RESTful Web Services by Florian MotlikJSUG - RESTful Web Services by Florian Motlik
JSUG - RESTful Web Services by Florian Motlik
 
Link.javaLink.javapackage com.bookstore.domain.model;import .docx
Link.javaLink.javapackage com.bookstore.domain.model;import .docxLink.javaLink.javapackage com.bookstore.domain.model;import .docx
Link.javaLink.javapackage com.bookstore.domain.model;import .docx
 
Apache Beam de A à Z
 Apache Beam de A à Z Apache Beam de A à Z
Apache Beam de A à Z
 
SAStrutsから読み取るFWの進化
SAStrutsから読み取るFWの進化SAStrutsから読み取るFWの進化
SAStrutsから読み取るFWの進化
 
RESTful Web Services with Jersey
RESTful Web Services with JerseyRESTful Web Services with Jersey
RESTful Web Services with Jersey
 
Making Java REST with JAX-RS 2.0
Making Java REST with JAX-RS 2.0Making Java REST with JAX-RS 2.0
Making Java REST with JAX-RS 2.0
 
Overview of GraphQL & Clients
Overview of GraphQL & ClientsOverview of GraphQL & Clients
Overview of GraphQL & Clients
 
Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET Core
 
Building Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET CoreBuilding Beautiful REST APIs in ASP.NET Core
Building Beautiful REST APIs in ASP.NET Core
 
03 form-data
03 form-data03 form-data
03 form-data
 
Querydsl fin jug - june 2012
Querydsl   fin jug - june 2012Querydsl   fin jug - june 2012
Querydsl fin jug - june 2012
 
Jersey
JerseyJersey
Jersey
 
Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]
 
Using Java to implement RESTful Web Services: JAX-RS
Using Java to implement RESTful Web Services: JAX-RSUsing Java to implement RESTful Web Services: JAX-RS
Using Java to implement RESTful Web Services: JAX-RS
 
PigSPARQL: A SPARQL Query Processing Baseline for Big Data
PigSPARQL: A SPARQL Query Processing Baseline for Big DataPigSPARQL: A SPARQL Query Processing Baseline for Big Data
PigSPARQL: A SPARQL Query Processing Baseline for Big Data
 
Building Restful Web Services with Java
Building Restful Web Services with JavaBuilding Restful Web Services with Java
Building Restful Web Services with Java
 
Objects, Testing, and Responsibility
Objects, Testing, and ResponsibilityObjects, Testing, and Responsibility
Objects, Testing, and Responsibility
 

Más de Ricardo Longa

Big Data como Serviço: da captura à visualização de dados com alto desempenho
Big Data como Serviço: da captura à visualização de dados com alto desempenhoBig Data como Serviço: da captura à visualização de dados com alto desempenho
Big Data como Serviço: da captura à visualização de dados com alto desempenhoRicardo Longa
 
Minicurso sobre AndroidAnnotations, GreenDAO, EventBus e Crouton
Minicurso sobre AndroidAnnotations, GreenDAO, EventBus e CroutonMinicurso sobre AndroidAnnotations, GreenDAO, EventBus e Crouton
Minicurso sobre AndroidAnnotations, GreenDAO, EventBus e CroutonRicardo Longa
 
Treze ferramentas/frameworks para desenvolvimento android
Treze ferramentas/frameworks para desenvolvimento androidTreze ferramentas/frameworks para desenvolvimento android
Treze ferramentas/frameworks para desenvolvimento androidRicardo Longa
 
Aula 05/06 (Service)
Aula 05/06 (Service)Aula 05/06 (Service)
Aula 05/06 (Service)Ricardo Longa
 
Aula 05/06 (Notification)
Aula 05/06 (Notification)Aula 05/06 (Notification)
Aula 05/06 (Notification)Ricardo Longa
 
Aula 29/05 (AlarmManager)
Aula 29/05 (AlarmManager)Aula 29/05 (AlarmManager)
Aula 29/05 (AlarmManager)Ricardo Longa
 
Aula 22/05 (Handler)
Aula 22/05 (Handler)Aula 22/05 (Handler)
Aula 22/05 (Handler)Ricardo Longa
 
Aula 6 - 08/05 (SharedPreferences)
Aula 6 - 08/05 (SharedPreferences)Aula 6 - 08/05 (SharedPreferences)
Aula 6 - 08/05 (SharedPreferences)Ricardo Longa
 
Aula 6 - 08/05 (Menu)
Aula 6 - 08/05 (Menu)Aula 6 - 08/05 (Menu)
Aula 6 - 08/05 (Menu)Ricardo Longa
 
Aula 5 - 24/04 (Landscape / Portrait)
Aula 5 - 24/04 (Landscape / Portrait)Aula 5 - 24/04 (Landscape / Portrait)
Aula 5 - 24/04 (Landscape / Portrait)Ricardo Longa
 
Aula 17 04 (Exercícios e ScrollView)
Aula 17 04 (Exercícios e ScrollView)Aula 17 04 (Exercícios e ScrollView)
Aula 17 04 (Exercícios e ScrollView)Ricardo Longa
 
Aula 10 04 (intents)
Aula 10 04 (intents)Aula 10 04 (intents)
Aula 10 04 (intents)Ricardo Longa
 
Aula 10 04 (Gerenciadores de layouts)
Aula 10 04 (Gerenciadores de layouts)Aula 10 04 (Gerenciadores de layouts)
Aula 10 04 (Gerenciadores de layouts)Ricardo Longa
 
Android - Programação para dispositivos móveis (Aula 2)
Android - Programação para dispositivos móveis (Aula 2)Android - Programação para dispositivos móveis (Aula 2)
Android - Programação para dispositivos móveis (Aula 2)Ricardo Longa
 
Android - Programação para dispositivos móveis (Aula 1)
Android - Programação para dispositivos móveis (Aula 1)Android - Programação para dispositivos móveis (Aula 1)
Android - Programação para dispositivos móveis (Aula 1)Ricardo Longa
 
Da introdução à prática no desenvolvimento Android
Da introdução à prática no desenvolvimento AndroidDa introdução à prática no desenvolvimento Android
Da introdução à prática no desenvolvimento AndroidRicardo Longa
 

Más de Ricardo Longa (20)

Big Data como Serviço: da captura à visualização de dados com alto desempenho
Big Data como Serviço: da captura à visualização de dados com alto desempenhoBig Data como Serviço: da captura à visualização de dados com alto desempenho
Big Data como Serviço: da captura à visualização de dados com alto desempenho
 
Minicurso sobre AndroidAnnotations, GreenDAO, EventBus e Crouton
Minicurso sobre AndroidAnnotations, GreenDAO, EventBus e CroutonMinicurso sobre AndroidAnnotations, GreenDAO, EventBus e Crouton
Minicurso sobre AndroidAnnotations, GreenDAO, EventBus e Crouton
 
Treze ferramentas/frameworks para desenvolvimento android
Treze ferramentas/frameworks para desenvolvimento androidTreze ferramentas/frameworks para desenvolvimento android
Treze ferramentas/frameworks para desenvolvimento android
 
Aula 12/06 (SQLite)
Aula 12/06 (SQLite)Aula 12/06 (SQLite)
Aula 12/06 (SQLite)
 
Aula 05/06 (Service)
Aula 05/06 (Service)Aula 05/06 (Service)
Aula 05/06 (Service)
 
Aula 05/06 (Notification)
Aula 05/06 (Notification)Aula 05/06 (Notification)
Aula 05/06 (Notification)
 
Aula 29/05 (AlarmManager)
Aula 29/05 (AlarmManager)Aula 29/05 (AlarmManager)
Aula 29/05 (AlarmManager)
 
Aula 22/05 (Handler)
Aula 22/05 (Handler)Aula 22/05 (Handler)
Aula 22/05 (Handler)
 
Adopt a JSR
Adopt a JSRAdopt a JSR
Adopt a JSR
 
Aula 6 - 08/05 (SharedPreferences)
Aula 6 - 08/05 (SharedPreferences)Aula 6 - 08/05 (SharedPreferences)
Aula 6 - 08/05 (SharedPreferences)
 
Aula 6 - 08/05 (Menu)
Aula 6 - 08/05 (Menu)Aula 6 - 08/05 (Menu)
Aula 6 - 08/05 (Menu)
 
Aula 5 - 24/04 (Landscape / Portrait)
Aula 5 - 24/04 (Landscape / Portrait)Aula 5 - 24/04 (Landscape / Portrait)
Aula 5 - 24/04 (Landscape / Portrait)
 
JBoss Forge 2
JBoss Forge 2JBoss Forge 2
JBoss Forge 2
 
Aula 17 04 (Exercícios e ScrollView)
Aula 17 04 (Exercícios e ScrollView)Aula 17 04 (Exercícios e ScrollView)
Aula 17 04 (Exercícios e ScrollView)
 
Aula 10 04 (intents)
Aula 10 04 (intents)Aula 10 04 (intents)
Aula 10 04 (intents)
 
Aula 10 04 (Gerenciadores de layouts)
Aula 10 04 (Gerenciadores de layouts)Aula 10 04 (Gerenciadores de layouts)
Aula 10 04 (Gerenciadores de layouts)
 
Android - Programação para dispositivos móveis (Aula 2)
Android - Programação para dispositivos móveis (Aula 2)Android - Programação para dispositivos móveis (Aula 2)
Android - Programação para dispositivos móveis (Aula 2)
 
Android - Programação para dispositivos móveis (Aula 1)
Android - Programação para dispositivos móveis (Aula 1)Android - Programação para dispositivos móveis (Aula 1)
Android - Programação para dispositivos móveis (Aula 1)
 
Da introdução à prática no desenvolvimento Android
Da introdução à prática no desenvolvimento AndroidDa introdução à prática no desenvolvimento Android
Da introdução à prática no desenvolvimento Android
 
Open Networking
Open NetworkingOpen Networking
Open Networking
 

Último

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 

Último (20)

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 

JSR 339 - Java API for RESTful Web Services

  • 1. JSR 339 Java API for RESTful Web Services
  • 2. GujavaSC / Adopt a JSR Membros do GujavaSC Participação Adopt a JSR Grupo de estudos Artigos Palestras
  • 3. O que é REST?
  • 4. É um estilo arquitetural…
  • 5. Estilo arquitetural??? É um estilo arquitetural…
  • 8. Características Recursos são identificados por um ID; Sem estado; Vincule as coisas; Múltiplas representações; Interface uniforme.
  • 9. Características Recursos são identificados por um ID; Sem estado; Vincule as coisas; Múltiplas representações; Interface uniforme.
  • 10. Interface Uniforme Verbos HTTP Ação POST Cria um novo recurso PUT Atualiza um recurso DELETE Remove um recurso GET Retorna um recurso
  • 11. JAX-RS 1.x Final Release em 2008 Objetivos Baseado em POJO Centralizado em HTTP Independência de formato Independência de container Inclusão no Java EE 6
  • 12. Exemplo JAX-RS 1.0 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  • 13. Exemplo JAX-RS 1.0 http://localhost:8080/rest-example/resources/books/year/2011?name=Book1 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } }
  • 14. Exemplo JAX-RS 1.0 http://localhost:8080/rest-example/resources/books/year/2011?name=Book1 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } }
  • 15. @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") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  • 17. Exemplo JAX-RS 1.0 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  • 18. Exemplo JAX-RS 1.0 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  • 19. Exemplo JAX-RS 1.0 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  • 20. Exemplo JAX-RS 1.0 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public Response listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); ResponseBuilder rb = Response.ok(books); return rb.build(); } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  • 21. Exemplo JAX-RS 1.0 @Path("books") public class BookResource { @GET @Path("/year/{year}") @Produces(MediaType.APPLICATION_JSON) public List<Book> listByYearAndName(@PathParam("year") Integer year, @QueryParam("name") String name) { List<Book> books = getListByYearAndName(year, name); // ResponseBuilder rb = Response.ok(books); // return rb.build(); return books; } } http://localhost:8080/rest-example/resources/books/year/2011?name=Book1
  • 22. JAX-RS 2.0 Final Release em Maio de 2013 Solicitações (JSR 339) Client API Asynchronous processing Filters / Interceptors Bean Validation Hypermedia MVC
  • 24. Client API Baseada na API do Jersey (versão 1.x); Consumir serviços criados em qualquer linguagem.
  • 25. Qual é o recurso?
  • 26. Book!
  • 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
  • 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 com a 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()); }
  • 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()); }
  • 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()); }
  • 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. Como configurar Filters e Interceptors?
  • 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()); }
  • 66. Que tal uma chamada 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étodo get() 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 um InvocationCallback?
  • 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(); } }); }
  • 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 for com 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()); } }
  • 105. O que são os filters?
  • 107. @Provider public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  • 108. @Provider public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  • 109. @Provider public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  • 110. @Provider public class LoggingFilter implements ClientRequestFilter, ClientResponseFilter { public void filter(ClientRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { log(responseContext); } }
  • 111. @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); } }
  • 113. @Provider class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  • 114. @Provider class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  • 115. @Provider class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  • 116. @Provider class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  • 117. @Provider class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { public void filter(ContainerRequestContext requestContext) throws IOException { log(requestContext); } public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log(responseContext); } }
  • 118. O que são os interceptors?
  • 121. @Provider public class GzipReaderInterceptor implements ReaderInterceptor { Object aroundReadFrom(ReaderInterceptorContext ctx) ... { if (isGzipped(ctx)) { InputStream old = ctx.getInputStream(); ctx.setInputStream(new GZIPInputStream(old)); try { return ctx.proceed(); } finally { ctx.setInputStream(old); } } else { return ctx.proceed(); } } }
  • 122. @Provider public class GzipReaderInterceptor implements ReaderInterceptor { Object aroundReadFrom(ReaderInterceptorContext ctx) ... { if (isGzipped(ctx)) { InputStream old = ctx.getInputStream(); ctx.setInputStream(new GZIPInputStream(old)); try { return ctx.proceed(); } finally { ctx.setInputStream(old); } } else { return ctx.proceed(); } } }
  • 123. @Provider public class GzipReaderInterceptor implements ReaderInterceptor { Object aroundReadFrom(ReaderInterceptorContext ctx) ... { if (isGzipped(ctx)) { InputStream old = ctx.getInputStream(); ctx.setInputStream(new GZIPInputStream(old)); try { return ctx.proceed(); } finally { ctx.setInputStream(old); } } else { return ctx.proceed(); } } }
  • 124. @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(); } } }
  • 126. @Provider public class GzipWriteInterceptor implements WriteInterceptor { void aroundWriteTo(WriterInterceptorContext ctx) ... { OutputStream old = ctx.getOutputStream(); GZIPOutputStream gzipOutputStream = new GZIPOutputStream(old); ctx.setOutputStream(gzipOutputStream); updateHeaders(ctx); try { ctx.proceed(); } finally { gzipOutputStream.finish(); ctx.setOutputStream(old); } } }
  • 127. @Provider public class GzipWriteInterceptor implements WriteInterceptor { void aroundWriteTo(WriterInterceptorContext ctx) ... { OutputStream old = ctx.getOutputStream(); GZIPOutputStream gzipOutputStream = new GZIPOutputStream(old); ctx.setOutputStream(gzipOutputStream); updateHeaders(ctx); try { ctx.proceed(); } finally { gzipOutputStream.finish(); ctx.setOutputStream(old); } } }
  • 128. @Provider public class GzipWriteInterceptor implements WriteInterceptor { void aroundWriteTo(WriterInterceptorContext ctx) ... { OutputStream old = ctx.getOutputStream(); GZIPOutputStream gzipOutputStream = new GZIPOutputStream(old); ctx.setOutputStream(gzipOutputStream); updateHeaders(ctx); try { ctx.proceed(); } finally { gzipOutputStream.finish(); ctx.setOutputStream(old); } } }
  • 129. @Provider public class GzipWriteInterceptor implements WriteInterceptor { void aroundWriteTo(WriterInterceptorContext ctx) ... { OutputStream old = ctx.getOutputStream(); GZIPOutputStream gzipOutputStream = new GZIPOutputStream(old); ctx.setOutputStream(gzipOutputStream); updateHeaders(ctx); try { ctx.proceed(); } finally { gzipOutputStream.finish(); ctx.setOutputStream(old); } } }
  • 130. Mas, qual é a diferença mesmo?
  • 131. Filters: Acesso ao contexto do request/response.
  • 132. Exemplo de Filters Logar origem do request. Verificar qual o método http utilizado. Qual a URI.
  • 133. Interceptors: Acesso ao contexto da mensagem.
  • 134. Exemplo de Interceptors Compactar o conteúdo da mensagem a ser enviada. Descompactar o conteúdo da mensagem a ser lida.
  • 135. Posso logar minhas requisições antes de chegar ao método?
  • 137. @Provider @PreMatching public class HttpPreMatchingFilter implements ContainerRequestFilter { public void filter(ContainerRequestContext requestContext) throws IOException { ... } }
  • 138. @Provider @PreMatching public class HttpPreMatchingFilter implements ContainerRequestFilter { public void filter(ContainerRequestContext requestContext) throws IOException { ... } }
  • 139. @Provider @PreMatching public class HttpPreMatchingFilter implements ContainerRequestFilter { public void filter(ContainerRequestContext requestContext) throws IOException { ... } }
  • 140. Mas se eu quiser logar um método específico, é possível?
  • 142. @NameBinding @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(value = RetentionPolicy.RUNTIME) public @interface Logged {} Similar aos qualificadores do CDI
  • 143. @Provider @Logged public class LoggingFilter 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?
  • 148. Modifier and Type Constant Field Value public static final int AUTHENTICATION 1000 public static final int AUTHORIZATION 2000 public static final int ENTITY_CODER 3000 public static final int HEADER_DECORATOR 4000 public static final int USER 5000 javax.ws.rs.Priorities
  • 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(@Valid Book 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 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)
  • 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 Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  • 158. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  • 159. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  • 160. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  • 161. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  • 162. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  • 163. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  • 164. Links Transicionais @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response read(@PathParam("id") Integer id, @Context UriInfo uriInfo){ Link purchaseLink = Link.fromPath(uriInfo.getRequestUri().toString() + "/purchase") .rel("purchase") .build(); return Response.ok(readObject(id)) .links(purchaseLink) .link(uriInfo.getRequestUri().toString() + "/genre/programming", "genre") .build(); }
  • 165. Integração com Java EE 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