I wantet to set up a simple demo Project on how to use Restygwt, for learning. I followed this Tutorial: https://ronanquillevere.github.io/2014/03/16/gwt-rest-app.html So far I got this on my client: In my SearchPresenter the method searchBook(String isbn) gets triggered when I click a button
@Override
public void searchBook(String isbn) {
clientContext.getBookStoreClient().getBook(isbn, new MethodCallback<List<Book>>() {
@Override
public void onFailure(Method method, Throwable exception) {
Window.alert("Failure");
GWT.log(exception.getMessage());
GWT.log(stackTraceToString(exception));
}
@Override
public void onSuccess(Method method, List<Book> response) {
for (Book book : response) {
Window.alert(book.getIsbn() + " " + book.getAuthor());
}
}
});
}
private String stackTraceToString(Throwable e) {
StringBuilder sb = new StringBuilder();
for (StackTraceElement element : e.getStackTrace()) {
sb.append(element.toString());
sb.append("\n");
}
return sb.toString();
}
My BookstoreClient looks like this:
@Path("/api/bookstore/books")
public interface BookstoreClient extends RestService{
@GET
public void getBooks(MethodCallback<List<Book>> callback);
@GET
@Path("/{isbn}")
public void getBook(@PathParam("isbn") String isbn, MethodCallback<List<Book>> callback);
}
The BookResource on my Server:
@Path("books")
public class BookResource {
Map<String, Book> books;
public BookResource() {
books = new HashMap<>();
Book book1 = new Book("1", "Max Mustermann");
books.put(book1.getIsbn(), book1);
Book book2 = new Book("2", "Erika mustermann");
books.put(book2.getIsbn(), book2);
}
@GET
@Produces("application/json")
public Collection<Book> getBooks() {
return books.values();
}
@GET
@Path("/{isbn}")
@Produces("application/json")
public Book getBook(@PathParam("isbn") String isbn) {
return books.get(isbn);
}
}
And the Book in my shared Package
public class Book {
private final String isbn;
private final String author;
@JsonCreator
public Book(@JsonProperty("isbn")String isbn, @JsonProperty("author")String author) {
this.isbn = isbn;
this.author = author;
}
public String getIsbn() {
return isbn;
}
public String getAuthor() {
return author;
}
}
But if I click the Button on my GUI I jump into the onFailure and get the Exception:
Response was NOT a valid JSON document
Unknown.Throwable_4_g$(GWT_Selenium-0.js@8:4312)
Unknown.Exception_4_g$(GWT_Selenium-0.js@18:4550)
Unknown.RuntimeException_4_g$(GWT_Selenium-0.js@18:4597)
Unknown.new ResponseFormatException_2_g$(GWT_Selenium-0.js@25:51000)
Unknown.parseResult_2_g$(GWT_Selenium-0.js@23:33367)
Unknown.parseResult_1_g$(GWT_Selenium-0.js@15:33355)
Unknown.onResponseReceived_0_g$(GWT_Selenium-0.js@27:33312)
Unknown.fireOnResponseReceived_0_g$(GWT_Selenium-0.js@17:14339)
Unknown.onReadyStateChange_0_g$(GWT_Selenium-0.js@28:14647)
Unknown.<anonymous>(GWT_Selenium-0.js@18:30998)
Unknown.apply_0_g$(GWT_Selenium-0.js@28:5498)
Unknown.entry0_0_g$(GWT_Selenium-0.js@16:5554)
Unknown.<anonymous>(GWT_Selenium-0.js@14:5534)
But if I go to url:
http://127.0.0.1:8888/api/bookstore/books
I get the following shown in My Browser
[{"isbn":"1","author":"Max Mustermann"},{"isbn":"2","author":"Erika mustermann"}]
Did I miss something or screwed up on the implementation of the RestService? Thanks in Advance for any comment, youre Help is apreciatet
Your question says that the error happens when you click a button, and the button does a search by isbn - it doesn't call GET /api/bookstore/books
like you tested in the browser. This is what it actually does:
@GET
@Path("/{isbn}")
public void getBook(@PathParam("isbn") String isbn, MethodCallback<List<Book>> callback);
This client-side method expects a List<Book>
, but on the server you defined
@GET
@Path("/{isbn}")
@Produces("application/json")
public Book getBook(@PathParam("isbn") String isbn)
which returns a single book, not wrapped in a list. This is likely the source of your error.