2012-08-27 1 views
5

Sto giocando con questo Google Toolkit/esempio GSON che ottiene i dati da Twitter.Totale Noob a gwt/gson in eclissi, errore: "Impossibile richiamare il costruttore no-args per la classe"

Tutto sta compilando bene, ma quando il debug di applicazioni Web, i carichi tutto bene, ma quando fa clic sul pulsante "cerca" ottengo il seguente errore:

SEVERE: javax.servlet.ServletContext log: Exception while dispatching incoming RPC call com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract java.util.List com.google.gwt.twittersearch.client.TwitterService.searchTweets(java.lang.String) throws java.io.IOException,java.lang.IllegalArgumentException' threw an unexpected exception: java.lang.RuntimeException: Unable to invoke no-args constructor for class com.google.gwt.twittersearch.server.TwitterServiceImpl$SearchResponse. Register an InstanceCreator with Gson for this type may fix this problem. at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:385) at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:588) at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:208) at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248) at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166) at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:35) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:60) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:94) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:370) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) at org.mortbay.jetty.Server.handle(Server.java:326) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755) at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409) at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582) Caused by: java.lang.RuntimeException: Unable to invoke no-args constructor for class com.google.gwt.twittersearch.server.TwitterServiceImpl$SearchResponse. Register an InstanceCreator with Gson for this type may fix this problem. at com.google.gson.internal.ConstructorConstructor$8.construct(ConstructorConstructor.java:167) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:162) at com.google.gson.Gson.fromJson(Gson.java:795) at com.google.gson.Gson.fromJson(Gson.java:734) at com.google.gwt.twittersearch.server.TwitterServiceImpl.parseSearchResponse(TwitterServiceImpl.java:80) at com.google.gwt.twittersearch.server.TwitterServiceImpl.searchTweets(TwitterServiceImpl.java:35) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:115) at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:569) ... 34 more Caused by: java.lang.UnsupportedOperationException: Cannot allocate class com.google.gwt.twittersearch.server.TwitterServiceImpl$SearchResponse at com.google.gson.internal.UnsafeAllocator$4.newInstance(UnsafeAllocator.java:100) at com.google.gson.internal.ConstructorConstructor$8.construct(ConstructorConstructor.java:164) ... 45 more

ecco il codice TwitterServiceImpl :

package com.google.gwt.twittersearch.server; 

import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.Reader; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import java.net.URLEncoder; 
import java.util.List; 

import com.google.gwt.twittersearch.client.Tweet; 
import com.google.gwt.twittersearch.client.TwitterService; 
import com.google.gson.Gson; 
import com.google.gwt.user.server.rpc.RemoteServiceServlet; 

@SuppressWarnings("serial") 
public class TwitterServiceImpl extends RemoteServiceServlet implements 
     TwitterService { 

    @Override 
    public List<Tweet> searchTweets(String query) throws IllegalArgumentException, IOException { 
      query = query.trim(); 
      if (query.isEmpty()) { 
      throw new IllegalArgumentException("No search query specified."); 
      } 

      // see: https://dev.twitter.com/docs/api/1/get/search 
      String q = URLEncoder.encode(query, "UTF-8"); 
      URL url = new URL("http://search.twitter.com/search.json?q=" + q); 
      HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
      InputStream response = null; 
      try { 
      response = connection.getInputStream(); 
      return parseSearchResponse(response); 
      } finally { 
      if (response != null) { 
       response.close(); 
      } 
      } 
    } 

    @Override 
    public String getPrivacyPolicy() throws IOException { 
     // see: https://dev.twitter.com/docs/api/1/get/legal/privacy 
     URL url = new URL("https://api.twitter.com/1/legal/privacy.json"); 
     HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
     InputStream response = null; 
     try { 
      response = connection.getInputStream(); 
      return parsePolicyResponse(response); 
     } finally { 
      if (response != null) { 
       response.close(); 
      } 
     } 
    } 

    /** 
    * Parses the privacy policy response returned from the Twitter API. 
    * @param response the response 
    * @return the privacy policy 
    * @throws IOException if there was a problem reading the response 
    */ 
    private String parsePolicyResponse(InputStream response) throws IOException { 
     Reader reader = new InputStreamReader(response); 
     PrivacyPolicyResponse privacyPolicyResponse = new Gson().fromJson(reader, PrivacyPolicyResponse.class); 
     return privacyPolicyResponse.privacy; 
    } 

    /** 
    * Parses the search response returned from the Twitter API. 
    * @param response the response 
    * @return the search results 
    * @throws IOException if there was a problem reading the response 
    */ 

    private List<Tweet> parseSearchResponse(InputStream response) throws IOException { 
      Reader reader = new InputStreamReader(response); 
      SearchResponse searchResponse = new Gson().fromJson(reader, SearchResponse.class); 
      return searchResponse.results; 
     } 

    private class PrivacyPolicyResponse { 
    public String privacy; 
    } 


    private class SearchResponse { 
     public List<Tweet> results; 
    } 

} 

ecco il codice punto di ingresso:

package com.google.gwt.twittersearch.client; 

import java.util.List; 
import com.google.gwt.safehtml.shared.SafeHtmlBuilder; 
import com.google.gwt.core.client.EntryPoint; 
import com.google.gwt.core.client.GWT; 
import com.google.gwt.event.dom.client.ClickEvent; 
import com.google.gwt.event.dom.client.ClickHandler; 
import com.google.gwt.user.client.rpc.AsyncCallback; 
import com.google.gwt.user.client.ui.Button; 
import com.google.gwt.user.client.ui.HTML; 
import com.google.gwt.user.client.ui.HorizontalPanel; 
import com.google.gwt.user.client.ui.Image; 
import com.google.gwt.user.client.ui.Label; 
import com.google.gwt.user.client.ui.Panel; 
import com.google.gwt.user.client.ui.RootPanel; 
import com.google.gwt.user.client.ui.TextBox; 
import com.google.gwt.user.client.ui.VerticalPanel; 

/** 
* Entry point classes define <code>onModuleLoad()</code>. 
*/ 
public class TwitterSearch implements EntryPoint { 
    private Button privacyPolicyButton; 
    private Button searchButton; 
    private TextBox searchQueryTextBox; 
    private Panel resultsPanel; 
    private Label errorLabel; 
    private Image loadingImage; 
    private final TwitterServiceAsync service = GWT.create(TwitterService.class); 

/** 
* This is the entry point method. 
*/ 
public void onModuleLoad() { 
    createWidgets(); 
    layoutWidgets(); 

} 

private void createWidgets() { 
    searchQueryTextBox = new TextBox(); 

    searchButton = new Button("Search"); 
    searchButton.addClickHandler(new ClickHandler() { 
     @Override 
     public void onClick(ClickEvent event) { 
      setLoading(true); 
      String query = searchQueryTextBox.getText(); 
      service.searchTweets(query, new AsyncCallback<List<Tweet>>() { 
       @Override 
       public void onFailure(Throwable caught) { 
        errorLabel.setText(caught.getMessage()); 
        errorLabel.setVisible(true); 
        setLoading(false); 
       } 

       @Override 
       public void onSuccess(List<Tweet> result) { 
        resultsPanel.clear(); 
        for (Tweet tweet : result) { 
         SafeHtmlBuilder builder = new SafeHtmlBuilder(); 
         builder.appendHtmlConstant("<b>User: </b>"); 
         builder.appendEscaped(tweet.getFrom_user()); 
         builder.appendHtmlConstant("<br /><b>Created: </b>"); 
         builder.appendEscaped(tweet.getCreated_at()); 
         builder.appendHtmlConstant("<br /><b>Tweet: </b>"); 
         builder.appendEscaped(tweet.getText()); 
         builder.appendHtmlConstant("<br /><br />"); 
         resultsPanel.add(new HTML(builder.toSafeHtml())); 
        } 
        setLoading(false); 
       } 
      }); 
     } 
    }); 

    privacyPolicyButton = new Button("Privacy Policy"); 
    privacyPolicyButton.addClickHandler(new ClickHandler() { 
     @Override 
     public void onClick(ClickEvent event) { 
      setLoading(true); 
      service.getPrivacyPolicy(new AsyncCallback<String>() { 
       @Override 
       public void onFailure(Throwable caught) { 
        errorLabel.setText(caught.getMessage()); 
        errorLabel.setVisible(true); 
        setLoading(false); 
       } 

       @Override 
       public void onSuccess(String result) { 
        resultsPanel.clear(); 

        // convert newlines to <br /> 
        SafeHtmlBuilder builder = new SafeHtmlBuilder(); 
        builder.appendEscapedLines(result); 

        resultsPanel.add(new HTML(builder.toSafeHtml())); 

        setLoading(false); 
       } 
      }); 
     } 
    }); 

    resultsPanel = new VerticalPanel(); 

    errorLabel = new Label(); 
    errorLabel.addStyleName("errorLabel"); 
    errorLabel.setVisible(false); 

    //image from http://loadinfo.net/ 
    loadingImage = new Image("loading.gif"); 
    loadingImage.setVisible(false); 
} 

private void layoutWidgets() { 
    Panel panel = new VerticalPanel(); 

    panel.add(errorLabel); 

    Panel horizPanel = new HorizontalPanel(); 
    horizPanel.add(searchQueryTextBox); 
    horizPanel.add(searchButton); 
    horizPanel.add(privacyPolicyButton); 
    horizPanel.add(loadingImage); 
    panel.add(horizPanel); 

    panel.add(resultsPanel); 

    RootPanel.get().add(panel); 
} 

/** 
* Updates the UI for when a RPC call is made. 
* @param loading true if an RPC call is being sent, false if not 
*/ 
private void setLoading(boolean loading) { 
    if (loading) { 
     errorLabel.setVisible(false); 
    } 
    searchQueryTextBox.setEnabled(!loading); 
    searchButton.setEnabled(!loading); 
    privacyPolicyButton.setEnabled(!loading); 
    loadingImage.setVisible(loading); 
} 
} 

Qui i s il codice tweet:

package com.google.gwt.twittersearch.client; 

import java.io.Serializable; 

@SuppressWarnings("serial") 
public class Tweet implements Serializable{ 
private String id; 
    private String from_user; 
    private String created_at; 
    private String text; 

    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    public String getFrom_user() { 
     return from_user; 
    } 

    public void setFrom_user(String from_user) { 
     this.from_user = from_user; 
    } 

    public String getCreated_at() { 
     return created_at; 
    } 

    public void setCreated_at(String created_at) { 
     this.created_at = created_at; 
    } 

    public String getText() { 
     return text; 
    } 

    public void setText(String text) { 
     this.text = text; 
    } 


} 

Qualsiasi comprensione di questo errore o di dove potrei andare da qui sarebbe molto apprezzato!

Grazie, BRL

risposta

6

è necessario aggiungere un costruttore senza argomenti quali:

public class Tweet implements Serializable{ 

    public Tweet(){ 
    } 

} 

EDIT

Sarà inoltre necessario uno anche qui

private class SearchResponse { 

    public SearchResponse(){ 
    } 
    public List<Tweet> results; 
} 

per gestire il tuo errore java.lang.RuntimeException: Unable to invoke no-args constructor for class

Una classe definita dall'utente è serializzabile se:

  1. la classe è assegnabile a IsSerializable o java.io.Serializable, sia perché realizza una di queste interfacce, o perché è derivata da una superclasse che implementa una di queste interfacce.

  2. tutti i non-finale della classe, campi di istanza non transitori sono serializzabile

  3. la classe ha un default pubblico (argomento zero) costruttore

above is from this tutorial

+0

Hoepfully non l'ho fatto fare qualcosa di stupido ma ho provato questo e sto ancora ricevendo lo stesso errore.Ho provato questo: 'public public Tweet implementa Serializable { \t ID stringa privato; \t stringa privata from_user; \t stringa privata created_at; \t testo String privato; \t \t/** pubblico Tweet (String twit_id, String twit_user, String twit_created, String twit_text) { \t * \t id = twit_id; \t * \t from_user = twit_user; \t * \t created_at = twit_created; \t * \t text = twit_text; \t} */ \t \t pubblico Tweet() { \t \t \t} \t \t public String getId() { \t \t \t ritorno id; } e ho anche provato con la parte commentata non commentata – brl8

+0

@ user1628648 vedere i miei commenti modificati. È inoltre necessario un costruttore no-args per SearchResponse. – user1258245