net.javaforge.blog - GWT: Creating REST Services with Jersey and RestyGWT

Install this theme
GWT: Creating REST Services with Jersey and RestyGWT

GWT-RPC is known to be a preferred way to implement client-server communication in GWT. Sometimes however it is a good idea to implement server-client communication using REST (e.g. backend services for non-GWT clients, application’s REST API for the world outside etc…)

In this small tutorial we’ll create a simple REST service with Jersey Framework on the serverside and a corresponding REST client with RestyGWT library on the clientside (GWT-side).

Check out the complete maven example project on GitHub: https://github.com/bigpuritz/javaforge-blog/tree/master/restgwt

First we need some domain model class:

public class Person {
 private int id;
 private String name;
 private Date dateOfBirth;
 public Person() {
 }
 public Person(int id, String name, Date dateOfBirth) {
 this.id = id;
 this.name = name;
 this.dateOfBirth = dateOfBirth;
 }
 // getter / setter goes here
}

Now let’s create Person’s REST resource using Jersey:

@Path("/person")
public class PersonResource {
 private static final Logger logger = LoggerFactory
 .getLogger(PersonResource.class);
 private static int counter = 1;
 @GET
 @Produces(MediaType.APPLICATION_JSON)
 public List getPersons() {
 List persons = new ArrayList();
 for (int i = 0; i < 5; i++) {
 persons.add(new Person(counter, "name-" + counter, new Date()));
 counter++;
 }
 logger.info("Returning {} persons...", persons.size());
 return persons;
 }
}

On each http request http://…../rest/person it will return 5 persons as JSON like this:

[
 {"id":1,"name":"name-1","dateOfBirth":1346268802016},
 {"id":2,"name":"name-2","dateOfBirth":1346268802016},
 {"id":3,"name":"name-3","dateOfBirth":1346268802016},
 {"id":4,"name":"name-4","dateOfBirth":1346268802016},
 {"id":5,"name":"name-5","dateOfBirth":1346268802016}
]

Last thing to be done on the serverside is a Jersey configuration in web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
 PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
 <servlet>
 <servlet-name>jersey-rest</servlet-name>
 <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
 <init-param>
 <param-name>com.sun.jersey.config.property.packages</param-name>
 <param-value>net.javaforge.gwt.rest.server.remote.rest</param-value>
 </init-param>
 <init-param>
 <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
 <param-value>true</param-value>
 </init-param>
 <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
 <servlet-name>jersey-rest</servlet-name>
 <url-pattern>/rest/*</url-pattern>
 </servlet-mapping>
 <!-- Default page to serve -->
 <welcome-file-list>
 <welcome-file>App.html</welcome-file>
 </welcome-file-list>
</web-app>

Furthermore we need to create a REST client, that will be used as asynchronous remote service in our GWT classes. Writing a REST proxy with RestyGWT is fairly straightforward:

public interface PersonResourceAsync extends RestService {
 @GET
 void getPersons(MethodCallback<List> callback);
 /**
 * Utility class to get the instance of the Rest Service
 */
 public static final class Util {
 private static PersonResourceAsync instance;
 public static final PersonResourceAsync get() {
 if (instance == null) {
 instance = GWT.create(PersonResourceAsync.class);
 ((RestServiceProxy) instance).setResource(new Resource(
 "rest/person"));
 }
 return instance;
 }
 private Util() {
 // Utility class should not be instantiated
 }
 }
}

Now we can write simple GWT EntryPoint that populates a table from the Person’s REST resource on button click:

public class App implements EntryPoint {
 private FlexTable personsTable;
 static {
 // if you don't do this, on JSON response you'll get something like
 // this:
 // "Could not parse response: org.fusesource.restygwt.client.ResponseFormatException: Response was NOT a valid JSON document"
 Defaults.setDateFormat(null);
 }
 @Override
 public void onModuleLoad() {
 Button button = new Button("load persons");
 button.addClickHandler(new ClickHandler() {
 @Override
 public void onClick(ClickEvent event) {
 loadPersons();
 }
 });
 personsTable = new FlexTable();
 personsTable.setCellPadding(1);
 personsTable.setCellSpacing(0);
 personsTable.setWidth("600px");
 RootPanel.get().add(button);
 RootPanel.get().add(personsTable);
 }
 private void loadPersons() {
 PersonResourceAsync.Util.get().getPersons(
 new MethodCallback<List>() {
 @Override
 public void onSuccess(Method method, List persons) {
 if (personsTable.getRowCount() == 0) { // add header
 personsTable.setText(0, 0, "ID");
 personsTable.setText(0, 1, "NAME");
 personsTable.setText(0, 2, "DATE OF BIRTH");
 personsTable.getRowFormatter().addStyleName(0,
 "tableHeader");
 }
 for (Person p : persons) {
 int rowNum = personsTable.getRowCount();
 personsTable.setText(rowNum, 0,
 String.valueOf(p.getId()));
 personsTable.setText(rowNum, 1, p.getName());
 personsTable.setText(rowNum, 2,
 String.valueOf(p.getDateOfBirth()));
 }
 }
 @Override
 public void onFailure(Method method, Throwable exception) {
 Window.alert("Error while loading persons! Cause: "
 + exception.getMessage());
 }
 });
 }
}
PRINT THIS POST WORDS: Notes: 2 View comments 8/29/12 — 10:12pm Short URL: https://tmblr.co/ZwTERuSO9SwR Filed under: #gwt #java #rest #jersey #restygwt
 
  1. naveenc liked this
  2. javaforge posted this
View the discussion thread
Blog comments powered by Disqus

AltStyle によって変換されたページ (->オリジナル) /