Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

of

Easy REST APIs with Jersey and RestyGWT Slide 1 Easy REST APIs with Jersey and RestyGWT Slide 2 Easy REST APIs with Jersey and RestyGWT Slide 3 Easy REST APIs with Jersey and RestyGWT Slide 4 Easy REST APIs with Jersey and RestyGWT Slide 5 Easy REST APIs with Jersey and RestyGWT Slide 6 Easy REST APIs with Jersey and RestyGWT Slide 7 Easy REST APIs with Jersey and RestyGWT Slide 8 Easy REST APIs with Jersey and RestyGWT Slide 9 Easy REST APIs with Jersey and RestyGWT Slide 10 Easy REST APIs with Jersey and RestyGWT Slide 11 Easy REST APIs with Jersey and RestyGWT Slide 12 Easy REST APIs with Jersey and RestyGWT Slide 13 Easy REST APIs with Jersey and RestyGWT Slide 14 Easy REST APIs with Jersey and RestyGWT Slide 15 Easy REST APIs with Jersey and RestyGWT Slide 16 Easy REST APIs with Jersey and RestyGWT Slide 17 Easy REST APIs with Jersey and RestyGWT Slide 18 Easy REST APIs with Jersey and RestyGWT Slide 19
Upcoming SlideShare
GWT integration with Vaadin
Next
Download to read offline and view in fullscreen.

2 Likes

Share

Download to read offline

Easy REST APIs with Jersey and RestyGWT

Download to read offline

Presentation from GWT.create 2015 on how to easily build a REST API that can be consumed via GWT or native mobile clients. Presentation video here: http://gwtcreate.com/videos/#rpc-jersey-resty-gwt

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Easy REST APIs with Jersey and RestyGWT

  1. 1. Easy REST APIs with Jersey and RestyGWT David Chandler turbomanage.wordpress.com
  2. 2. why RestyGWT? Ease of GWT-RPC Power of Command pattern Less boilerplate Easier testing
  3. 3. 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/
  4. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 17. finer points Text, JSON, XML via direct API — res.get()… CachingRetryingDispatcher ModelChangeEvent Objects with final fields (@JsonCreator) Polymorphism (@JsonSubTypes)
  18. 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. 19. Please rate this session at gwtcreate.com/agenda src github.com/turbomanage/listmaker David Chandler turbomanage.wordpress.com resty-gwt.github.io
  • roadlabs

    Apr. 5, 2019
  • road_zhang

    Jan. 15, 2017

Presentation from GWT.create 2015 on how to easily build a REST API that can be consumed via GWT or native mobile clients. Presentation video here: http://gwtcreate.com/videos/#rpc-jersey-resty-gwt

Views

Total views

4,358

On Slideshare

0

From embeds

0

Number of embeds

11

Actions

Downloads

45

Shares

0

Comments

0

Likes

2

×