eclipse中的总Noob到gwt/gson,错误:"无法为类调用no-args构造函数"

brl*_*rl8 5 gwt

我正在玩这个从Twitter获取数据的Google Web工具包/ GSON示例.

一切都编译得很好,但是当我作为Web应用程序调试时,一切都加载得很好,但当我点击"搜索"按钮时,我收到以下错误:

严重:javax.servlet.ServletContext日志:调度传入RPC调用时发生异常com.google.gwt.user.server.rpc.UnexpectedException:服务方法'public abstract java.util.List com.google.gwt.twittersearch.client.TwitterService .searchTweets(java.lang.String)抛出java.io.IOException,java.lang.IllegalArgumentException'引发了一个意外的异常:java.lang.RuntimeException:无法为类com.google.gwt.twittersearch调用no-args构造函数. server.TwitterServiceImpl $ SearchResponse.使用Gson为此类型注册InstanceCreator可以解决此问题.com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:385)com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:588)com.google .gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:208),位于com.google.gwt.user的com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248) .server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)在javax.servlet.http.HttpServlet.service(HttpServlet.java:637)的javax.servlet.http.HttpServlet.service(HttpServlet.java:717)at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)位于com.google.appengine.tools.development的org.mortbay.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1166). HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:35)位于com.google.appengine.api.blobstore.dev.ServeBl的org.mortbay.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1157)obFilter.doFilter(ServeBlobFilter.java:60)atg.mortbay.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1157)at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java: 43)在org.mortbay.jetty的com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)的org.mortbay.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1157)位于org.mortbay.jetty.servlet.ServletHandler的com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97)的.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1157)$ CachedChain.doFilter (ServletHandler.java:1157)org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)位于org.mortbay的org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216). orm.mortbay.jetty.handler.ContextHandler.handle中的jetty.servlet.SessionHandler.handle(SessionHandler.java:182)Handler.java:765)位于org.mortbay的com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:94)的org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)位于org.mortbay.jetty.handler.HandlerWrapper.handle的com.google.appengine.tools.development.JettyContainerService $ ApiProxyHandler.handle(JettyContainerService.java:370)上的.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) (HandlerWrapper.java:152)org.mortbay.jetty.Server.handle(Server.java:326)org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)atg.mortbay.jetty.HttpConnection $在Org.mortbay.jet的org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)org.mortbay.jet的org.mortbay.jet.HttpParser.parseAvailable(HttpParser.java:218)上的RequestHandler.content(HttpConnection.java:938) .httpConnection.handle(HttpConnection.java:404)位于org.mortbay.thread.QueuedThreadPool的org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)$ PoolThread.run(QueuedThreadPool.java:582)引起:java.lang.RuntimeException:无法为类com.google.gwt.twittersearch.server.TwitterServiceImpl $ SearchResponse调用no-args构造函数.使用Gson为此类型注册InstanceCreator可以解决此问题.com.google.gson.internal.ConstructorConstructor $ 8.construct(ConstructorConstructor.java:167)位于com.google.gson的com.google.gson.internal.bind.ReflectiveTypeAdapterFactory $ Adapter.read(ReflectiveTypeAdapterFactory.java:162).来自com.google.gwt.twittersearch.server.TwitterServiceImpl.parseSearchResponse(TwitterServiceImpl.java:80)的com.google.gson.Gson.fromJson(Gson.java:734)的Gson.fromJson(Gson.java:795)位于sun.reflect的sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)的sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method).google.gwt.twittersearch.server.TwitterServiceImpl.searchTweets(TwitterServiceImpl.java:35) .delegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect.Method.invoke(Method.java:597)com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java) :115)com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:569)... 34更多引起:java.lang.Unsupp ortedOperationException:无法在com.google.gson.internal.ConstructorConstructor $ 8的com.google.gson.internal.UnsafeAllocator $ 4.newInstance(UnsafeAllocator.java:100)中分配com.google.gwt.twittersearch.server.TwitterServiceImpl $ SearchResponse类. construct(ConstructorConstructor.java:164)......还有45个

这是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;
    }

}
Run Code Online (Sandbox Code Playgroud)

这是入口点代码:

    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);
}
}
Run Code Online (Sandbox Code Playgroud)

这是推文代码:

    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;
    }


}
Run Code Online (Sandbox Code Playgroud)

任何洞察这个错误或我可能会从这里去的地方将不胜感激!

谢谢,兄弟

use*_*245 6

您需要添加一个no-args构造函数,例如:

public class Tweet implements Serializable{

  public Tweet(){
  }

}
Run Code Online (Sandbox Code Playgroud)

编辑

你也需要一个

private class SearchResponse {

  public SearchResponse(){
  }
  public List<Tweet> results;
}
Run Code Online (Sandbox Code Playgroud)

处理你的错误 java.lang.RuntimeException: Unable to invoke no-args constructor for class

用户定义的类在以下情况下是可序列化的

  1. 该类可分配给IsSerializable或java.io.Serializable,因为它实现了这些接口之一,或者因为它是从实现这些接口之一的超类派生的.

  2. 所有类的非final,非瞬态实例字段都是可序列化的

  3. 该类有一个公共默认(零参数)构造函数

以上是本教程