Dropbox Java API dengan masalah Otentikasi GWT

Saya menggunakan Dropbox API untuk Java versi 1.6 yang dapat ditemukan di sini: https://www.dropbox.com/developers/core/sdks/java

Saya juga menggunakan GWT 2.5.1 di Eclipse 3.7

Saya memiliki kode berikut yang berfungsi ketika dijalankan sebagai Aplikasi Java:

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

Ini berfungsi dengan baik ketika saya menjalankannya sebagai Aplikasi Java. Namun, ketika saya mencoba melakukan hal serupa dengan GWT dalam RemoteServiceServlet. Saya mendapatkan pengecualian ketika saya mencoba melakukannya

webauth = new DbxWebAuthNoRedirect(requestConfig, appInfo);

Pengecualian yang saya dapatkan adalah sebagai berikut:

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

Saya telah membenturkan kepala ke dinding selama beberapa jam terakhir untuk mencari tahu apa yang sedang terjadi. Saya awalnya ingin menggunakan DbxWebAuth tetapi dokumentasi di API mereka menyertakan instruksi yang memiliki kelas yang tidak ada (saya berasumsi mereka melakukannya pada satu waktu).

Saya merasa DbxWebAuthNoRedirect melakukan sesuatu yang secara dinamis memuat koneksi berdasarkan kelas yang tersedia. Tapi saya belum bisa memahaminya.

Terima kasih sebelumnya atas bantuannya!

EDIT:

Oke, jadi saya melihat sumber API Dropbox dan kesalahan terjadi di sini:

    URL urlObject = new URL(url);
    HttpsURLConnection conn = (HttpsURLConnection) urlObject.openConnection(this.proxy);

Karena saya menggunakan Google App Engine, ia menggunakan objek URL-nya sendiri, bukan yang diimpor oleh App Engine API. Ada ide tentang solusi yang tidak melibatkan penulisan pembungkus GWT untuk API Dropbox.


person Joe    schedule 25.07.2013    source sumber
comment
Apakah Anda mengembangkan untuk mesin aplikasi Google? Jika demikian, kelas yang disebutkan dalam pesan kesalahan HttpsURLConnection seperti yang digunakan oleh api dropbox tidak kompatibel dengan cara kerja mesin aplikasi. Jika Anda tidak mengembangkan mesin aplikasi, Anda perlu menonaktifkan mesin aplikasi.   -  person Hilbrand Bouwkamp    schedule 25.07.2013
comment
Saya menggunakan GAE. Adakah ide untuk mengatasinya?   -  person Joe    schedule 25.07.2013
comment
Pada hasil edit Anda. GAE secara internal membuat konektor berdasarkan url yang diteruskan. Namun, karena api dropbox adalah url https dan oleh karena itu api dropbox mengharapkan kelas koneksi aman dikembalikan, ia melemparkannya ke kelas itu. Namun GAE hanya mendukung http dan akan mengembalikan konektor http tidak aman yang tidak dapat dialihkan ke kelas koneksi aman. Karena kode sumber api dropbox ada di github, Anda dapat mencoba mengubah kode tersebut menjadi objek yang tidak aman, tetapi saya tidak tahu apakah ini akan berhasil. (Sebagai catatan tambahan, ini bukan masalah GWT, tapi masalah GAE)   -  person Hilbrand Bouwkamp    schedule 26.07.2013


Jawaban (5)


Apakah Anda menggunakan url https:// yang aman untuk terhubung? Dugaan saya adalah jika Anda menggunakan http:// Anda mendapatkan konektor tidak aman yang tidak dapat dialihkan ke koneksi aman.

--edit--

Tampaknya kelas HttpsURLConnection tidak didukung di GAE, oleh karena itu kelas ini tidak akan berfungsi seperti yang disebutkan dalam dokumentasi GAE. Menggunakan HttpsURLConnection (masalah dokumen). Ini berarti Anda mungkin tidak ingin menggunakannya secara langsung.

person Hilbrand Bouwkamp    schedule 25.07.2013
comment
Sayangnya, saya tidak diberikan pilihan untuk jenis permintaan karena saya menggunakan API mereka. Saya baru saja memanggil metode finish pada instance DbxWebAuthNoRedirect yang mungkin menggunakan http, bukan https. Namun, saya skeptis terhadap hal ini karena ini menghasilkan situs https untuk dikunjungi untuk otentikasi. Mungkin GWT menghasilkan permintaan http, bukan https? Ini akan mengejutkan karena saya tidak mengalami masalah dalam mengimplementasikan Google Drive API dengan GWT. - person Joe; 26.07.2013
comment
Sepertinya sumber Dropbox menggunakan kelas URL Java yang diubah di GAE. Saya rasa saya mungkin dapat mengubah sumber Dropbox untuk memperbaiki masalah ini, tetapi saya tidak yakin. Ada ide? - person Joe; 26.07.2013
comment
Mulai Dropbox SDK for Java versi 2.0.5, Anda dapat menggunakan GoogleAppEngineHttpRequestor, yang memiliki dukungan eksplisit untuk API Pengambilan URL App Engine. - person Greg; 13.06.2016

Dropbox SDK terbaru memungkinkan Anda memilih implementasi HttpRequestor

new DbxRequestConfig(APP_NAME, userLocale, HttpRequestor);

Jadi yang perlu Anda lakukan hanyalah mengadaptasi com.dropbox.core.http.StandardHttpRequestor agar ramah Appengine

Inti: AppengineHttpRequestor.java

person radu-c    schedule 19.09.2013

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

Jadi dengan menggunakan Proxy (firewall saya) di StandardHttpRequestor dan menggunakan pemohon ini di DbxRequestConfig itu berhasil untuk saya.

person Sharad    schedule 31.10.2013

Saya juga menghadapi masalah yang sama. Sesuai postingan ini, https://groups.google.com/forum/#!topic/google-appengine-java/V8pREOXPX24,

com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler 
$Connection extends the class java.net.HttpURLConnection

Oleh karena itu saya mengganti kelas

javax.net.ssl.HttpsURLConnection

by

java.net.HttpURLConnection 

di kelas com.dropbox.core.http.StandardHttpRequestor dan membangun kembali Dropbox Java SDK. Ini berfungsi dengan baik. Contoh aplikasi yang berfungsi dapat ditemukan di https://gwt-gae-testing.appspot.com/

person user2489475    schedule 24.08.2013

Ini adalah satu-satunya cara untuk mengambil access_token (tetapi saya tidak tahu cara menangani metode lain dari 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();
}

Saya sarankan mengubah HttpRequestor seperti yang dikatakan @ radu-c. Ini berfungsi dengan baik.

person Aerox    schedule 23.05.2014