问题
I am using version 1.6 of the Dropbox API for Java found here: https://www.dropbox.com/developers/core/sdks/java
I am also using GWT 2.5.1 in Eclipse 3.7
I have the following code which works when run as a Java Applcation:
DbxRequestConfig requestConfig = new DbxRequestConfig(type, locale);
DbxAppInfo appInfo = new DbxAppInfo(APP_ID, APP_SECRET);
DbxWebAuthNoRedirect webauth = new DbxWebAuthNoRedirect(requestConfig, appInfo);
String result = webauth.start();
System.out.println(result);
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String code = reader.readLine();
webauth = new DbxWebAuthNoRedirect(requestConfig, appInfo);
DbxAuthFinish finish = webauth.finish(code);
DbxClient client = new DbxClient(requestConfig, finish.accessToken);
DbxAccountInfo info = client.getAccountInfo();
long total = info.quota.total;
long used = info.quota.normal;
System.out.println("total: " + total);
System.out.println("used: " + used);
This works just fin when I run it as a Java Application. However, when I try to do something similar with GWT within a RemoteServiceServlet. I get an exception when I try to do
webauth = new DbxWebAuthNoRedirect(requestConfig, appInfo);
The exception I am getting is the following:
Caused by: java.lang.ClassCastException: com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler$Connection cannot be cast to javax.net.ssl.HttpsURLConnection
at com.dropbox.core.http.StandardHttpRequestor.prepRequest(StandardHttpRequestor.java:160)
at com.dropbox.core.http.StandardHttpRequestor.startPost(StandardHttpRequestor.java:87)
at com.dropbox.core.http.StandardHttpRequestor.startPost(StandardHttpRequestor.java:21)
at com.dropbox.core.DbxRequestUtil.startPostNoAuth(DbxRequestUtil.java:156)
at com.dropbox.core.DbxRequestUtil.doPostNoAuth(DbxRequestUtil.java:289)
at com.dropbox.core.DbxWebAuthHelper.finish(DbxWebAuthHelper.java:40)
at com.dropbox.core.DbxWebAuthNoRedirect.finish(DbxWebAuthNoRedirect.java:84)
at com.cloudshare.server.DropboxPlayground.getFinish(DropboxPlayground.java:21)
at com.cloudshare.server.DropboxServiceImpl.authenticate(DropboxServiceImpl.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:115)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:561)
... 40 more
I have been banging my head against a wall for last couple of hours trying to figure out what is going on. I originally wanted to use a DbxWebAuth but the documentation in their API includes instructions that have classes that don't exist (I am assuming they did at one time).
I feel like the DbxWebAuthNoRedirect is doing something where it is dynamically loading a connection based on the classes that are available. But I have not been able to figure it out.
Thanks in advance for the help!
EDITS:
Okay, so I looked at the Dropbox API source and the error is occurring here:
URL urlObject = new URL(url);
HttpsURLConnection conn = (HttpsURLConnection) urlObject.openConnection(this.proxy);
Because I am using Google App Engine, it is using its own URL object rather than the one imported by the App Engine API. Any ideas on a solution that doesn't involve writting a GWT wrapper for the Dropbox API.
回答1:
Did you use a secure https://
url to connect? My guess is if you use a http://
you get the unsecured connector that can't be cast to a secure connection.
--edit--
It looks the HttpsURLConnection
class is simply not supported on GAE, therefor it will not work unlike the GAE documentation says. Using HttpsURLConnection (doc issue). This means you're probably out of luke using it directly.
回答2:
Latest Dropbox SDK lets you choose a HttpRequestor implementation
new DbxRequestConfig(APP_NAME, userLocale, HttpRequestor);
So all you need to do is adapt the com.dropbox.core.http.StandardHttpRequestor to be Appengine friendly
Gist: AppengineHttpRequestor.java
回答3:
DbxAppInfo appInfo = new DbxAppInfo(APP_KEY, APP_SECRET);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("107.108.85.10", 80));
StandardHttpRequestor requ = new StandardHttpRequestor(proxy);
DbxRequestConfig config = new DbxRequestConfig("JavaTutorial/1.0",
Locale.getDefault().toString(),requ);
DbxWebAuthNoRedirect webAuth = new DbxWebAuthNoRedirect(config, appInfo);
So by using Proxy
(my firewall) in StandardHttpRequestor
and using this requestor in DbxRequestConfig
it worked for me.
回答4:
I too faced the same issue. As per this post, https://groups.google.com/forum/#!topic/google-appengine-java/V8pREOXPX24,
com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler
$Connection extends the class java.net.HttpURLConnection
Hence I replaced the class
javax.net.ssl.HttpsURLConnection
by
java.net.HttpURLConnection
in class com.dropbox.core.http.StandardHttpRequestor and rebuild the Dropbox Java SDK. Its working fine. A sample working app can be at https://gwt-gae-testing.appspot.com/
回答5:
This is the only way to retrieve the access_token (but than i don't know how to handle the other method of Dropbox API).
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String code = req.getParameter("code");
URL fetchurl = new URL(url);
HTTPRequest request = new HTTPRequest(fetchurl, HTTPMethod.POST);
String body = "code=" + code + "&grant_type=authorization_code" + "&client_id=" + dropboKey + "&client_secret=" + dropboxSecret + "&redirect_uri=" + redirectUri;
request.setPayload(body.getBytes("UTF-8"));
HTTPResponse response = URLFetchServiceFactory.getURLFetchService().fetch(request);
String respInJson = new String(response.getContent());
LOGGER.warning(respInJson);
JSONObject jsonObj;
try {
jsonObj = new JSONObject(respInJson);
String uid=jsonObj.getString("uid");
String access_token=jsonObj.getString("access_token");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I suggest changing HttpRequestor as @radu-c said. It works fine.
来源:https://stackoverflow.com/questions/17866754/dropbox-java-api-with-gwt-authentication-problems