SlideShare a Scribd company logo
1 of 19
Download to read offline
Easy REST APIs with
Jersey and RestyGWT
David Chandler
turbomanage.wordpress.com
why RestyGWT?
Ease of GWT-RPC
Power of Command pattern
Less boilerplate
Easier testing
get started
pom.xml
<dependency>

<groupId>org.fusesource.restygwt</groupId>

<artifactId>restygwt</artifactId>

<version>1.4</version>

</dependency>

<dependency>

<groupId>javax.ws.rs</groupId>

<artifactId>jsr311-api</artifactId>

<version>1.1.1</version>

</dependency>

*.gwt.xml
<inherits name="org.fusesource.restygwt.RestyGWT"/>
https://resty-gwt.github.io/
map JSON
public class YqlResponse {

public YqlQuery query;



public static class YqlQuery {

public YqlResults results;



public static class YqlResults {

public List<Quote> quote;

}

}

}

no annotations needed
create a service API
@Path("http://query.yahooapis.com/v1/public")

public interface QuoteService extends RestService {

@GET

@Path("yql")

public void get(

@QueryParam("q") String query,

@QueryParam("env") String env,

@QueryParam("format") String format,

MethodCallback<YqlResponse> callback);

}

invoke the service
private static final QuoteService svc = GWT.create(QuoteService.class);



@Override

public void load(LoaderDemo.QuoteRequest input, final Callback<ListLoadResult<Quote>,
Throwable> callback) {

svc.get(input.getYql(), ENV, FORMAT, new MethodCallback<YqlResponse>() {

@Override

public void onFailure(Method method, Throwable throwable) {

Info.display("QuoteProxy", "failure");

callback.onFailure(throwable);

}



@Override

public void onSuccess(Method method, YqlResponse yqlResponse) {

List<Quote> quotes = yqlResponse.query.results.quote;

Info.display("QuoteProxy", "success");

callback.onSuccess(new ListLoadResultBean<Quote>(quotes));

}

});

}

simple CRUD API
public interface RestApi<T> extends RestService {



@GET

@Path("get")

public void get(@QueryParam("id")Long id, MethodCallback<T> callback);



@GET

@Path("all")

public void listAll(MethodCallback<ListResponse<T>> callback);



@POST

@Path("save")

public void save(T obj, MethodCallback<T> callback);



@POST

@Path("saveMany")

public void saveMany(List<T> obj, MethodCallback<Integer> callback);



@POST

@Path("delete")

public void delete(Long id, MethodCallback<Integer> callback);



}

not much here!
minimal boilerplate
@Path("/api/note")

public interface NoteItemRestService extends RestApi<Note> { }



private static final NoteItemRestService service = GWT.create(NoteItemRestService.class);



public void addNote(Display display, long listId, Note item)

{

NoteList noteList = App.getNoteListService().getNoteList(listId);

// All are 0-based for consistency with GWT constants

item.listId = listId;

service.save(item, new AppCallback<Note>(display) {

@Override

public void handleSuccess(Note result) {

App.getAppModel().getAllNotes().add(0, result);

App.getEventBus().fireEvent(new ShowMessageEvent("Note saved."));

App.getEventBus().fireEvent(new
NotesLoadedEvent(App.getAppModel().getAllNotes()));

App.getEventBus().fireEvent(new NoteAddedEvent(result));

}

});

}

public class ProjectEntryPoint implements EntryPoint {



private static DispatcherFactory dispatcherFactory = new DispatcherFactory();

private static FilterawareDispatcher dispatcher =
dispatcherFactory.cachingDispatcher();



@Override

public void onModuleLoad() {

// Configure RestyGWT

dispatcher.addFilter(new CORSFilter());

Defaults.setDispatcher(dispatcher);



LoaderDemo loaderDemo = new LoaderDemo();

RootPanel.get().add(loaderDemo);

}



}
ListAllNotesAction, ListAllNotesResult,

AddNoteAction, AddNoteResult, …
Command pattern
server side
@Path("api/note")

public class NoteDao extends RestServiceDao<Note>

{


private static final Logger LOG = Logger.getLogger(NoteDao.class.getName());



@Override

@Path("all")

@GET

public ListWrapper<Note> findAll() {

User user = AuthFilter.getUser();

List<Note> notes = this.listByOwner(user);

return new ListWrapper<Note>(notes);

}
. . .
}
Objectify + Jersey
@Produces(MediaType.APPLICATION_JSON)

public class RestServiceDao<T extends Owned> extends ObjectifyDao<T>

{



public T getForOwner() {

User user = AuthFilter.getUser();

T obj = null;

try {

obj = this.getByOwner(user);

return obj;

} catch (TooManyResultsException e) {

throw new WebApplicationException(e);

}

}



public ListWrapper<T> findAll() {

User user = AuthFilter.getUser();

List<T> userAll = this.listByOwner(user);

return new ListWrapper<T>(userAll);

}
. . .
}

getting Jersey
pom.xml
<dependency>

<groupId>org.glassfish.jersey.containers</groupId>

<!-- if your container implements Servlet API older than 3.0, 

use "jersey-container-servlet-core" -->

<artifactId>jersey-container-servlet-core</artifactId>

<version>2.7</version>

</dependency>

<!-- workaround for https://java.net/jira/browse/JERSEY-2459 -->

<dependency>

<groupId>org.glassfish.hk2</groupId>

<artifactId>hk2-api</artifactId>

<version>2.3.0-b09</version>

</dependency>

<dependency>

<groupId>com.fasterxml.jackson.jaxrs</groupId>

<artifactId>jackson-jaxrs-json-provider</artifactId>

<version>2.3.2</version>

</dependency>

Jersey config
web.xml
<servlet>

<servlet-name>jerseyServlet</servlet-name>

<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

<init-param>

<param-name>jersey.config.server.provider.packages</param-name>

<param-value>com.example.listmaker.server</param-value>

</init-param>

<init-param>

<!-- speed up initial Jersey loading by deactivating WADL -->

<param-name>jersey.config.server.wadl.disableWadl</param-name>

<param-value>true</param-value>

</init-param>

<init-param>

<param-name>jersey.config.server.provider.classnames</param-name>

<param-value>org.glassfish.jersey.filter.LoggingFilter</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>



<servlet-mapping>

<servlet-name>jerseyServlet</servlet-name>

<url-pattern>/listmaker/*</url-pattern>

</servlet-mapping>

what about auth?
AuthFilter.java
// if an API call, return JSON response

if (path.startsWith("/listmaker/api")) {

((HttpServletResponse) resp).setStatus(401);

resp.setContentType(MediaType.TEXT_PLAIN);

resp.getWriter().write("User must log in");

} else {

// otherwise redirect

httpRes.sendRedirect(LOGIN_FORM);

}
<filter>

<filter-name>AuthFilter</filter-name>

<filter-class>com.turbomanage.gwt.server.servlet.AuthFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>AuthFilter</filter-name>

<url-pattern>/listmaker/*</url-pattern>

</filter-mapping>

exception handling
@Override

public void onFailure(Method method, Throwable throwable) {

String url = method.builder.getUrl();



App.getLogger().log(Level.SEVERE, "Error calling service " + url, throwable);

try {

// Decode the exception

if (throwable instanceof FailedStatusCodeException) {

FailedStatusCodeException sce = (FailedStatusCodeException) throwable;

App.getLogger().log(Level.SEVERE, "Service returned " + sce.getStatusCode() +
sce.getMessage());

if (401 == sce.getStatusCode()) {

Window.Location.replace(LOGIN_FORM);

} else if (500 == sce.getStatusCode()) {

if ("UserNotRegisteredException".equals(sce.getMessage())) {

Window.Location.replace(SIGNUP_URL);

}

}

}

handleFailure(throwable);

} finally {

reset(null);

}

}

application error handling
service.save(item, new AppCallback<Note>(display) {

@Override

public void handleSuccess(Note result) {

. . .
}

});
public abstract class AppCallback<R> implements MethodCallback<R> {



private final Display display;



public AppCallback() {

this.display = null;

}



public AppCallback(Display display) {

this.display = display;

display.startProcessing();

}
. . .
}
finer points
Text, JSON, XML via direct API — res.get()…
CachingRetryingDispatcher
ModelChangeEvent
Objects with final fields (@JsonCreator)
Polymorphism (@JsonSubTypes)
same obj on client / server?
older versions of RestyGWT used Jackson 1.7
RestyGWT 2.0 uses Jackson 2.3
so you can now use the same annotations on client
and server
and therefore the same POJOs (yeah)!
use @JsonIgnore for server-only fields (like Ref)
Please rate this session at
gwtcreate.com/agenda
src
github.com/turbomanage/listmaker
David Chandler
turbomanage.wordpress.com
resty-gwt.github.io

More Related Content

What's hot

Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Andres Almiray
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code EffectivelyAndres Almiray
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaFabio Collini
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 SpringKiyotaka Oku
 
Architecture Components
Architecture ComponentsArchitecture Components
Architecture ComponentsSang Eel Kim
 
The Ring programming language version 1.9 book - Part 11 of 210
The Ring programming language version 1.9 book - Part 11 of 210The Ring programming language version 1.9 book - Part 11 of 210
The Ring programming language version 1.9 book - Part 11 of 210Mahmoud Samir Fayed
 
yagdao-0.3.1 JPA guide
yagdao-0.3.1 JPA guideyagdao-0.3.1 JPA guide
yagdao-0.3.1 JPA guideMert Can Akkan
 
The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42Yevhen Bobrov
 
What's new in Android O
What's new in Android OWhat's new in Android O
What's new in Android OKirill Rozov
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Ryosuke Uchitate
 
The Ring programming language version 1.5.3 book - Part 26 of 184
The Ring programming language version 1.5.3 book - Part 26 of 184The Ring programming language version 1.5.3 book - Part 26 of 184
The Ring programming language version 1.5.3 book - Part 26 of 184Mahmoud Samir Fayed
 
Spring & Hibernate
Spring & HibernateSpring & Hibernate
Spring & HibernateJiayun Zhou
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Fabio Collini
 
T.Y.B.S.CS Advance Java Practicals Sem 5 Mumbai University
T.Y.B.S.CS Advance Java Practicals Sem 5 Mumbai UniversityT.Y.B.S.CS Advance Java Practicals Sem 5 Mumbai University
T.Y.B.S.CS Advance Java Practicals Sem 5 Mumbai UniversityNiraj Bharambe
 

What's hot (20)

Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code Effectively
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJava
 
Finding Clojure
Finding ClojureFinding Clojure
Finding Clojure
 
Unit testing with mock libs
Unit testing with mock libsUnit testing with mock libs
Unit testing with mock libs
 
XTW_Import
XTW_ImportXTW_Import
XTW_Import
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
Junit 5 - Maior e melhor
Junit 5 - Maior e melhorJunit 5 - Maior e melhor
Junit 5 - Maior e melhor
 
Architecture Components
Architecture ComponentsArchitecture Components
Architecture Components
 
The Ring programming language version 1.9 book - Part 11 of 210
The Ring programming language version 1.9 book - Part 11 of 210The Ring programming language version 1.9 book - Part 11 of 210
The Ring programming language version 1.9 book - Part 11 of 210
 
yagdao-0.3.1 JPA guide
yagdao-0.3.1 JPA guideyagdao-0.3.1 JPA guide
yagdao-0.3.1 JPA guide
 
The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42
 
What's new in Android O
What's new in Android OWhat's new in Android O
What's new in Android O
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
 
The Ring programming language version 1.5.3 book - Part 26 of 184
The Ring programming language version 1.5.3 book - Part 26 of 184The Ring programming language version 1.5.3 book - Part 26 of 184
The Ring programming language version 1.5.3 book - Part 26 of 184
 
Spring & Hibernate
Spring & HibernateSpring & Hibernate
Spring & Hibernate
 
Open sourcing the store
Open sourcing the storeOpen sourcing the store
Open sourcing the store
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2
 
React lecture
React lectureReact lecture
React lecture
 
T.Y.B.S.CS Advance Java Practicals Sem 5 Mumbai University
T.Y.B.S.CS Advance Java Practicals Sem 5 Mumbai UniversityT.Y.B.S.CS Advance Java Practicals Sem 5 Mumbai University
T.Y.B.S.CS Advance Java Practicals Sem 5 Mumbai University
 

Viewers also liked

GWT integration with Vaadin
GWT integration with VaadinGWT integration with Vaadin
GWT integration with VaadinPeter Lehto
 
RestFull Webservices with JAX-RS
RestFull Webservices with JAX-RSRestFull Webservices with JAX-RS
RestFull Webservices with JAX-RSNeil Ghosh
 
JSR 339 - Java API for RESTful Web Services
JSR 339 - Java API for RESTful Web ServicesJSR 339 - Java API for RESTful Web Services
JSR 339 - Java API for RESTful Web ServicesDaniel Cunha
 
Real world RESTful service development problems and solutions
Real world RESTful service development problems and solutionsReal world RESTful service development problems and solutions
Real world RESTful service development problems and solutionsBhakti Mehta
 
Artsofte облегченная веб шина данных для организации дистанционных каналов пр...
Artsofte облегченная веб шина данных для организации дистанционных каналов пр...Artsofte облегченная веб шина данных для организации дистанционных каналов пр...
Artsofte облегченная веб шина данных для организации дистанционных каналов пр...Artsofte IT company
 
figo at FinTech Startups MeetUp in Hamburg
figo at FinTech Startups MeetUp in Hamburgfigo at FinTech Startups MeetUp in Hamburg
figo at FinTech Startups MeetUp in HamburgLars Markull
 
JAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesJAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesArun Gupta
 
Управление идентификационными данными и доступом
Управление идентификационными данными и доступомУправление идентификационными данными и доступом
Управление идентификационными данными и доступомКРОК
 
Необходимые условия качества данных: MDM, Шина, Хранилище данных
Необходимые условия качества данных: MDM, Шина, Хранилище данныхНеобходимые условия качества данных: MDM, Шина, Хранилище данных
Необходимые условия качества данных: MDM, Шина, Хранилище данныхКРОК
 
Интеграция данных и приложений: основа для единой ИТ-инфраструктуры
Интеграция данных и приложений: основа для единой ИТ-инфраструктурыИнтеграция данных и приложений: основа для единой ИТ-инфраструктуры
Интеграция данных и приложений: основа для единой ИТ-инфраструктурыКРОК
 
Open Source Integration with WSO2 Enterprise Service Bus
Open Source Integration  with  WSO2 Enterprise Service BusOpen Source Integration  with  WSO2 Enterprise Service Bus
Open Source Integration with WSO2 Enterprise Service Bussumedha.r
 
Oracle Service Bus vs. Oracle Enterprise Service Bus vs. BPEL
Oracle Service Bus vs. Oracle Enterprise Service Bus vs. BPELOracle Service Bus vs. Oracle Enterprise Service Bus vs. BPEL
Oracle Service Bus vs. Oracle Enterprise Service Bus vs. BPELGuido Schmutz
 
Enterprise service bus(esb)
Enterprise service bus(esb)Enterprise service bus(esb)
Enterprise service bus(esb)prksh89
 
Produktivität - 5 Tricks, um in weniger Zeit mehr zu erledigen
Produktivität - 5 Tricks, um in weniger Zeit mehr zu erledigenProduktivität - 5 Tricks, um in weniger Zeit mehr zu erledigen
Produktivität - 5 Tricks, um in weniger Zeit mehr zu erledigenFastBill
 
Microservices = Death of the Enterprise Service Bus (ESB)?
Microservices = Death of the Enterprise Service Bus (ESB)?Microservices = Death of the Enterprise Service Bus (ESB)?
Microservices = Death of the Enterprise Service Bus (ESB)?Kai Wähner
 
Become a Presentation Hero: 21 tips
Become a Presentation Hero: 21 tipsBecome a Presentation Hero: 21 tips
Become a Presentation Hero: 21 tipsTom De Ruyck
 

Viewers also liked (16)

GWT integration with Vaadin
GWT integration with VaadinGWT integration with Vaadin
GWT integration with Vaadin
 
RestFull Webservices with JAX-RS
RestFull Webservices with JAX-RSRestFull Webservices with JAX-RS
RestFull Webservices with JAX-RS
 
JSR 339 - Java API for RESTful Web Services
JSR 339 - Java API for RESTful Web ServicesJSR 339 - Java API for RESTful Web Services
JSR 339 - Java API for RESTful Web Services
 
Real world RESTful service development problems and solutions
Real world RESTful service development problems and solutionsReal world RESTful service development problems and solutions
Real world RESTful service development problems and solutions
 
Artsofte облегченная веб шина данных для организации дистанционных каналов пр...
Artsofte облегченная веб шина данных для организации дистанционных каналов пр...Artsofte облегченная веб шина данных для организации дистанционных каналов пр...
Artsofte облегченная веб шина данных для организации дистанционных каналов пр...
 
figo at FinTech Startups MeetUp in Hamburg
figo at FinTech Startups MeetUp in Hamburgfigo at FinTech Startups MeetUp in Hamburg
figo at FinTech Startups MeetUp in Hamburg
 
JAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesJAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web Services
 
Управление идентификационными данными и доступом
Управление идентификационными данными и доступомУправление идентификационными данными и доступом
Управление идентификационными данными и доступом
 
Необходимые условия качества данных: MDM, Шина, Хранилище данных
Необходимые условия качества данных: MDM, Шина, Хранилище данныхНеобходимые условия качества данных: MDM, Шина, Хранилище данных
Необходимые условия качества данных: MDM, Шина, Хранилище данных
 
Интеграция данных и приложений: основа для единой ИТ-инфраструктуры
Интеграция данных и приложений: основа для единой ИТ-инфраструктурыИнтеграция данных и приложений: основа для единой ИТ-инфраструктуры
Интеграция данных и приложений: основа для единой ИТ-инфраструктуры
 
Open Source Integration with WSO2 Enterprise Service Bus
Open Source Integration  with  WSO2 Enterprise Service BusOpen Source Integration  with  WSO2 Enterprise Service Bus
Open Source Integration with WSO2 Enterprise Service Bus
 
Oracle Service Bus vs. Oracle Enterprise Service Bus vs. BPEL
Oracle Service Bus vs. Oracle Enterprise Service Bus vs. BPELOracle Service Bus vs. Oracle Enterprise Service Bus vs. BPEL
Oracle Service Bus vs. Oracle Enterprise Service Bus vs. BPEL
 
Enterprise service bus(esb)
Enterprise service bus(esb)Enterprise service bus(esb)
Enterprise service bus(esb)
 
Produktivität - 5 Tricks, um in weniger Zeit mehr zu erledigen
Produktivität - 5 Tricks, um in weniger Zeit mehr zu erledigenProduktivität - 5 Tricks, um in weniger Zeit mehr zu erledigen
Produktivität - 5 Tricks, um in weniger Zeit mehr zu erledigen
 
Microservices = Death of the Enterprise Service Bus (ESB)?
Microservices = Death of the Enterprise Service Bus (ESB)?Microservices = Death of the Enterprise Service Bus (ESB)?
Microservices = Death of the Enterprise Service Bus (ESB)?
 
Become a Presentation Hero: 21 tips
Become a Presentation Hero: 21 tipsBecome a Presentation Hero: 21 tips
Become a Presentation Hero: 21 tips
 

Similar to Easy REST APIs with Jersey and RestyGWT

比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Multi Client Development with Spring for SpringOne 2GX 2013 with Roy Clarkson
Multi Client Development with Spring for SpringOne 2GX 2013 with Roy ClarksonMulti Client Development with Spring for SpringOne 2GX 2013 with Roy Clarkson
Multi Client Development with Spring for SpringOne 2GX 2013 with Roy ClarksonJoshua Long
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeMacoscope
 
Spring into rails
Spring into railsSpring into rails
Spring into railsHiro Asari
 
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
 
ASP.NET Web API
ASP.NET Web APIASP.NET Web API
ASP.NET Web APIhabib_786
 
Native REST Web Services with Oracle 11g
Native REST Web Services with Oracle 11gNative REST Web Services with Oracle 11g
Native REST Web Services with Oracle 11gMarcelo Ochoa
 
OSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian SchneiderOSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian Schneidermfrancis
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureC.T.Co
 
HTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R Auge
HTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R AugeHTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R Auge
HTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R Augemfrancis
 
Overview of RESTful web services
Overview of RESTful web servicesOverview of RESTful web services
Overview of RESTful web servicesnbuddharaju
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
Cloud nativeworkshop
Cloud nativeworkshopCloud nativeworkshop
Cloud nativeworkshopEmily Jiang
 
Testing in android
Testing in androidTesting in android
Testing in androidjtrindade
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasyJBug Italy
 

Similar to Easy REST APIs with Jersey and RestyGWT (20)

比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Multi Client Development with Spring for SpringOne 2GX 2013 with Roy Clarkson
Multi Client Development with Spring for SpringOne 2GX 2013 with Roy ClarksonMulti Client Development with Spring for SpringOne 2GX 2013 with Roy Clarkson
Multi Client Development with Spring for SpringOne 2GX 2013 with Roy Clarkson
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, Macoscope
 
Brief Intro To Jax Rs
Brief Intro To Jax RsBrief Intro To Jax Rs
Brief Intro To Jax Rs
 
Spring into rails
Spring into railsSpring into rails
Spring into rails
 
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
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
 
ASP.NET Web API
ASP.NET Web APIASP.NET Web API
ASP.NET Web API
 
Native REST Web Services with Oracle 11g
Native REST Web Services with Oracle 11gNative REST Web Services with Oracle 11g
Native REST Web Services with Oracle 11g
 
OSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian SchneiderOSGi ecosystems compared on Apache Karaf - Christian Schneider
OSGi ecosystems compared on Apache Karaf - Christian Schneider
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
HTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R Auge
HTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R AugeHTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R Auge
HTTP Whiteboard - OSGI Compendium 6.0 - How web apps should have been! - R Auge
 
Servlets
ServletsServlets
Servlets
 
Overview of RESTful web services
Overview of RESTful web servicesOverview of RESTful web services
Overview of RESTful web services
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
Cloud nativeworkshop
Cloud nativeworkshopCloud nativeworkshop
Cloud nativeworkshop
 
Testing in android
Testing in androidTesting in android
Testing in android
 
May 2010 - RestEasy
May 2010 - RestEasyMay 2010 - RestEasy
May 2010 - RestEasy
 

More from David Chandler

Taking Your GWT App to Tablets with GXT 4.0
Taking Your GWT App to Tablets with GXT 4.0Taking Your GWT App to Tablets with GXT 4.0
Taking Your GWT App to Tablets with GXT 4.0David Chandler
 
StORM: a lightweight ORM for Android SQLite
StORM: a lightweight ORM for Android SQLiteStORM: a lightweight ORM for Android SQLite
StORM: a lightweight ORM for Android SQLiteDavid Chandler
 
Cómo trabajan los Googlers
Cómo trabajan los GooglersCómo trabajan los Googlers
Cómo trabajan los GooglersDavid Chandler
 
Google App Engine Update 2012
Google App Engine Update 2012Google App Engine Update 2012
Google App Engine Update 2012David Chandler
 
Scalable Apps with Google App Engine
Scalable Apps with Google App EngineScalable Apps with Google App Engine
Scalable Apps with Google App EngineDavid Chandler
 
Develop and Deploy Scalable Apps with Google App Engine
Develop and Deploy Scalable Apps with Google App EngineDevelop and Deploy Scalable Apps with Google App Engine
Develop and Deploy Scalable Apps with Google App EngineDavid Chandler
 
The 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for JavaThe 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for JavaDavid Chandler
 
Securing JSF Applications Against the OWASP Top Ten
Securing JSF Applications Against the OWASP Top TenSecuring JSF Applications Against the OWASP Top Ten
Securing JSF Applications Against the OWASP Top TenDavid Chandler
 

More from David Chandler (14)

Taking Your GWT App to Tablets with GXT 4.0
Taking Your GWT App to Tablets with GXT 4.0Taking Your GWT App to Tablets with GXT 4.0
Taking Your GWT App to Tablets with GXT 4.0
 
StORM: a lightweight ORM for Android SQLite
StORM: a lightweight ORM for Android SQLiteStORM: a lightweight ORM for Android SQLite
StORM: a lightweight ORM for Android SQLite
 
Cómo trabajan los Googlers
Cómo trabajan los GooglersCómo trabajan los Googlers
Cómo trabajan los Googlers
 
Life of an engineer
Life of an engineerLife of an engineer
Life of an engineer
 
StORM preview
StORM previewStORM preview
StORM preview
 
Google App Engine Update 2012
Google App Engine Update 2012Google App Engine Update 2012
Google App Engine Update 2012
 
GWT Plus HTML 5
GWT Plus HTML 5GWT Plus HTML 5
GWT Plus HTML 5
 
Scalable Apps with Google App Engine
Scalable Apps with Google App EngineScalable Apps with Google App Engine
Scalable Apps with Google App Engine
 
What's New in GWT 2.2
What's New in GWT 2.2What's New in GWT 2.2
What's New in GWT 2.2
 
Develop and Deploy Scalable Apps with Google App Engine
Develop and Deploy Scalable Apps with Google App EngineDevelop and Deploy Scalable Apps with Google App Engine
Develop and Deploy Scalable Apps with Google App Engine
 
Secrets of the GWT
Secrets of the GWTSecrets of the GWT
Secrets of the GWT
 
The 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for JavaThe 90-Day Startup with Google AppEngine for Java
The 90-Day Startup with Google AppEngine for Java
 
GWT MVP Case Study
GWT MVP Case StudyGWT MVP Case Study
GWT MVP Case Study
 
Securing JSF Applications Against the OWASP Top Ten
Securing JSF Applications Against the OWASP Top TenSecuring JSF Applications Against the OWASP Top Ten
Securing JSF Applications Against the OWASP Top Ten
 

Recently uploaded

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is insideshinachiaurasa2
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburgmasabamasaba
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyviewmasabamasaba
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastPapp Krisztián
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durbanmasabamasaba
 
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...masabamasaba
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 

Recently uploaded (20)

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban
 
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 

Easy REST APIs with Jersey and RestyGWT

  • 1. Easy REST APIs with Jersey and RestyGWT David Chandler turbomanage.wordpress.com
  • 2. why RestyGWT? Ease of GWT-RPC Power of Command pattern Less boilerplate Easier testing
  • 4. map JSON public class YqlResponse {
 public YqlQuery query;
 
 public static class YqlQuery {
 public YqlResults results;
 
 public static class YqlResults {
 public List<Quote> quote;
 }
 }
 }
 no annotations needed
  • 5. create a service API @Path("http://query.yahooapis.com/v1/public")
 public interface QuoteService extends RestService {
 @GET
 @Path("yql")
 public void get(
 @QueryParam("q") String query,
 @QueryParam("env") String env,
 @QueryParam("format") String format,
 MethodCallback<YqlResponse> callback);
 }

  • 6. invoke the service private static final QuoteService svc = GWT.create(QuoteService.class);
 
 @Override
 public void load(LoaderDemo.QuoteRequest input, final Callback<ListLoadResult<Quote>, Throwable> callback) {
 svc.get(input.getYql(), ENV, FORMAT, new MethodCallback<YqlResponse>() {
 @Override
 public void onFailure(Method method, Throwable throwable) {
 Info.display("QuoteProxy", "failure");
 callback.onFailure(throwable);
 }
 
 @Override
 public void onSuccess(Method method, YqlResponse yqlResponse) {
 List<Quote> quotes = yqlResponse.query.results.quote;
 Info.display("QuoteProxy", "success");
 callback.onSuccess(new ListLoadResultBean<Quote>(quotes));
 }
 });
 }

  • 7. simple CRUD API public interface RestApi<T> extends RestService {
 
 @GET
 @Path("get")
 public void get(@QueryParam("id")Long id, MethodCallback<T> callback);
 
 @GET
 @Path("all")
 public void listAll(MethodCallback<ListResponse<T>> callback);
 
 @POST
 @Path("save")
 public void save(T obj, MethodCallback<T> callback);
 
 @POST
 @Path("saveMany")
 public void saveMany(List<T> obj, MethodCallback<Integer> callback);
 
 @POST
 @Path("delete")
 public void delete(Long id, MethodCallback<Integer> callback);
 
 }

  • 8. not much here! minimal boilerplate @Path("/api/note")
 public interface NoteItemRestService extends RestApi<Note> { }
 
 private static final NoteItemRestService service = GWT.create(NoteItemRestService.class);
 
 public void addNote(Display display, long listId, Note item)
 {
 NoteList noteList = App.getNoteListService().getNoteList(listId);
 // All are 0-based for consistency with GWT constants
 item.listId = listId;
 service.save(item, new AppCallback<Note>(display) {
 @Override
 public void handleSuccess(Note result) {
 App.getAppModel().getAllNotes().add(0, result);
 App.getEventBus().fireEvent(new ShowMessageEvent("Note saved."));
 App.getEventBus().fireEvent(new NotesLoadedEvent(App.getAppModel().getAllNotes()));
 App.getEventBus().fireEvent(new NoteAddedEvent(result));
 }
 });
 }

  • 9. public class ProjectEntryPoint implements EntryPoint {
 
 private static DispatcherFactory dispatcherFactory = new DispatcherFactory();
 private static FilterawareDispatcher dispatcher = dispatcherFactory.cachingDispatcher();
 
 @Override
 public void onModuleLoad() {
 // Configure RestyGWT
 dispatcher.addFilter(new CORSFilter());
 Defaults.setDispatcher(dispatcher);
 
 LoaderDemo loaderDemo = new LoaderDemo();
 RootPanel.get().add(loaderDemo);
 }
 
 } ListAllNotesAction, ListAllNotesResult,
 AddNoteAction, AddNoteResult, … Command pattern
  • 10. server side @Path("api/note")
 public class NoteDao extends RestServiceDao<Note>
 { 
 private static final Logger LOG = Logger.getLogger(NoteDao.class.getName());
 
 @Override
 @Path("all")
 @GET
 public ListWrapper<Note> findAll() {
 User user = AuthFilter.getUser();
 List<Note> notes = this.listByOwner(user);
 return new ListWrapper<Note>(notes);
 } . . . }
  • 11. Objectify + Jersey @Produces(MediaType.APPLICATION_JSON)
 public class RestServiceDao<T extends Owned> extends ObjectifyDao<T>
 {
 
 public T getForOwner() {
 User user = AuthFilter.getUser();
 T obj = null;
 try {
 obj = this.getByOwner(user);
 return obj;
 } catch (TooManyResultsException e) {
 throw new WebApplicationException(e);
 }
 }
 
 public ListWrapper<T> findAll() {
 User user = AuthFilter.getUser();
 List<T> userAll = this.listByOwner(user);
 return new ListWrapper<T>(userAll);
 } . . . }

  • 12. getting Jersey pom.xml <dependency>
 <groupId>org.glassfish.jersey.containers</groupId>
 <!-- if your container implements Servlet API older than 3.0, 
 use "jersey-container-servlet-core" -->
 <artifactId>jersey-container-servlet-core</artifactId>
 <version>2.7</version>
 </dependency>
 <!-- workaround for https://java.net/jira/browse/JERSEY-2459 -->
 <dependency>
 <groupId>org.glassfish.hk2</groupId>
 <artifactId>hk2-api</artifactId>
 <version>2.3.0-b09</version>
 </dependency>
 <dependency>
 <groupId>com.fasterxml.jackson.jaxrs</groupId>
 <artifactId>jackson-jaxrs-json-provider</artifactId>
 <version>2.3.2</version>
 </dependency>

  • 13. Jersey config web.xml <servlet>
 <servlet-name>jerseyServlet</servlet-name>
 <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
 <init-param>
 <param-name>jersey.config.server.provider.packages</param-name>
 <param-value>com.example.listmaker.server</param-value>
 </init-param>
 <init-param>
 <!-- speed up initial Jersey loading by deactivating WADL -->
 <param-name>jersey.config.server.wadl.disableWadl</param-name>
 <param-value>true</param-value>
 </init-param>
 <init-param>
 <param-name>jersey.config.server.provider.classnames</param-name>
 <param-value>org.glassfish.jersey.filter.LoggingFilter</param-value>
 </init-param>
 <load-on-startup>1</load-on-startup>
 </servlet>
 
 <servlet-mapping>
 <servlet-name>jerseyServlet</servlet-name>
 <url-pattern>/listmaker/*</url-pattern>
 </servlet-mapping>

  • 14. what about auth? AuthFilter.java // if an API call, return JSON response
 if (path.startsWith("/listmaker/api")) {
 ((HttpServletResponse) resp).setStatus(401);
 resp.setContentType(MediaType.TEXT_PLAIN);
 resp.getWriter().write("User must log in");
 } else {
 // otherwise redirect
 httpRes.sendRedirect(LOGIN_FORM);
 } <filter>
 <filter-name>AuthFilter</filter-name>
 <filter-class>com.turbomanage.gwt.server.servlet.AuthFilter</filter-class>
 </filter>
 <filter-mapping>
 <filter-name>AuthFilter</filter-name>
 <url-pattern>/listmaker/*</url-pattern>
 </filter-mapping>

  • 15. exception handling @Override
 public void onFailure(Method method, Throwable throwable) {
 String url = method.builder.getUrl();
 
 App.getLogger().log(Level.SEVERE, "Error calling service " + url, throwable);
 try {
 // Decode the exception
 if (throwable instanceof FailedStatusCodeException) {
 FailedStatusCodeException sce = (FailedStatusCodeException) throwable;
 App.getLogger().log(Level.SEVERE, "Service returned " + sce.getStatusCode() + sce.getMessage());
 if (401 == sce.getStatusCode()) {
 Window.Location.replace(LOGIN_FORM);
 } else if (500 == sce.getStatusCode()) {
 if ("UserNotRegisteredException".equals(sce.getMessage())) {
 Window.Location.replace(SIGNUP_URL);
 }
 }
 }
 handleFailure(throwable);
 } finally {
 reset(null);
 }
 }

  • 16. application error handling service.save(item, new AppCallback<Note>(display) {
 @Override
 public void handleSuccess(Note result) {
 . . . }
 }); public abstract class AppCallback<R> implements MethodCallback<R> {
 
 private final Display display;
 
 public AppCallback() {
 this.display = null;
 }
 
 public AppCallback(Display display) {
 this.display = display;
 display.startProcessing();
 } . . . }
  • 17. finer points Text, JSON, XML via direct API — res.get()… CachingRetryingDispatcher ModelChangeEvent Objects with final fields (@JsonCreator) Polymorphism (@JsonSubTypes)
  • 18. same obj on client / server? older versions of RestyGWT used Jackson 1.7 RestyGWT 2.0 uses Jackson 2.3 so you can now use the same annotations on client and server and therefore the same POJOs (yeah)! use @JsonIgnore for server-only fields (like Ref)
  • 19. Please rate this session at gwtcreate.com/agenda src github.com/turbomanage/listmaker David Chandler turbomanage.wordpress.com resty-gwt.github.io