Dropbox Java API ที่มีปัญหาการตรวจสอบสิทธิ์ GWT

ฉันใช้ Dropbox API เวอร์ชัน 1.6 สำหรับ Java ที่นี่: https://www.dropbox.com/developers/core/sdks/java

ฉันยังใช้ GWT 2.5.1 ใน Eclipse 3.7 ด้วย

ฉันมีรหัสต่อไปนี้ซึ่งใช้งานได้เมื่อทำงานเป็น 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);

ใช้งานได้ดีเมื่อฉันเรียกใช้เป็นแอปพลิเคชัน Java อย่างไรก็ตาม เมื่อฉันพยายามทำสิ่งที่คล้ายกับ GWT ภายใน RemoteServiceServlet ฉันได้รับข้อยกเว้นเมื่อฉันพยายามทำ

webauth = new DbxWebAuthNoRedirect(requestConfig, appInfo);

ข้อยกเว้นที่ฉันได้รับคือ:

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

ฉันเอาหัวโขกกำแพงมาสองสามชั่วโมงแล้วเพื่อพยายามคิดว่าเกิดอะไรขึ้น เดิมทีฉันต้องการใช้ DbxWebAuth แต่เอกสารประกอบใน API มีคำแนะนำที่ไม่มีคลาสอยู่ (ฉันถือว่าพวกเขาทำในคราวเดียว)

ฉันรู้สึกว่า DbxWebAuthNoRedirect กำลังทำบางสิ่งโดยโหลดการเชื่อมต่อแบบไดนามิกตามคลาสที่มีอยู่ แต่ฉันไม่สามารถเข้าใจได้

ขอบคุณล่วงหน้าสำหรับความช่วยเหลือ!

แก้ไข:

เอาล่ะ ฉันจึงดูแหล่งที่มาของ Dropbox API และเกิดข้อผิดพลาดที่นี่:

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

เนื่องจากฉันใช้ Google App Engine จึงใช้ออบเจ็กต์ URL ของตัวเอง แทนที่จะใช้ออบเจ็กต์ที่นำเข้าโดย App Engine API แนวคิดใดๆ เกี่ยวกับโซลูชันที่ไม่เกี่ยวข้องกับการเขียน GWT wrapper สำหรับ Dropbox API


person Joe    schedule 25.07.2013    source แหล่งที่มา
comment
คุณกำลังพัฒนาสำหรับ Google App Engine หรือไม่? หากเป็นเช่นนั้น คลาสที่ระบุในข้อความแสดงข้อผิดพลาด HttpsURLConnection ที่ใช้โดย dropbox api เข้ากันไม่ได้กับวิธีการทำงานของ App Engine หากคุณไม่ได้พัฒนาสำหรับ app engine คุณต้องปิดการใช้งาน app-engine   -  person Hilbrand Bouwkamp    schedule 25.07.2013
comment
ฉันใช้ GAE มีความคิดเห็นเกี่ยวกับการทำงานบ้างไหม?   -  person Joe    schedule 25.07.2013
comment
ในการแก้ไขของคุณ GAE จะสร้างตัวเชื่อมต่อภายในตาม URL ที่ส่งผ่าน อย่างไรก็ตาม เนื่องจาก dropbox api เป็น https url และด้วยเหตุนี้ dropbox api จึงคาดว่าคลาสการเชื่อมต่อที่ปลอดภัยจะถูกส่งกลับ จึงส่งไปที่คลาสนั้น อย่างไรก็ตาม GAE รองรับเฉพาะ http และจะส่งคืนตัวเชื่อมต่อ http ที่ไม่ปลอดภัย ซึ่งไม่สามารถส่งไปยังคลาสการเชื่อมต่อที่ปลอดภัยได้ เนื่องจากซอร์สโค้ดของ dropbox api อยู่บน github คุณจึงสามารถลองเปลี่ยนโค้ดเป็นวัตถุที่ไม่ปลอดภัยได้ แต่ฉันไม่รู้ว่าจะได้ผลหรือไม่ (ตามหมายเหตุด้านข้างนี่ไม่ใช่ปัญหา GWT แต่เป็นปัญหา GAE)   -  person Hilbrand Bouwkamp    schedule 26.07.2013


คำตอบ (5)


คุณใช้ https:// url ที่ปลอดภัยในการเชื่อมต่อหรือไม่ ฉันเดาว่าถ้าคุณใช้ http:// คุณจะได้รับตัวเชื่อมต่อที่ไม่ปลอดภัยซึ่งไม่สามารถส่งไปยังการเชื่อมต่อที่ปลอดภัยได้

--แก้ไข--

ดูเหมือนว่าคลาส HttpsURLConnection นั้นไม่รองรับ GAE ดังนั้นมันจะไม่ทำงานเหมือนที่เอกสาร GAE ระบุไว้ การใช้ HttpsURLConnection (ปัญหาเอกสาร) ซึ่งหมายความว่าคุณอาจใช้มันไม่ได้โดยตรง

person Hilbrand Bouwkamp    schedule 25.07.2013
comment
ขออภัย ฉันไม่ได้รับตัวเลือกสำหรับประเภทคำขอเนื่องจากฉันใช้ API ของพวกเขา ฉันเพิ่งเรียกวิธีการเสร็จสิ้นบนอินสแตนซ์ของ DbxWebAuthNoRedirect ซึ่งอาจใช้ http แทน https อย่างไรก็ตาม ฉันไม่มั่นใจในเรื่องนี้เพราะมันสร้างไซต์ https เพื่อเข้าชมเพื่อตรวจสอบสิทธิ์ บางที GWT กำลังสร้างคำขอ http แทนที่จะเป็น https นี่คงเป็นเรื่องที่น่าแปลกใจเนื่องจากฉันไม่มีปัญหาในการใช้งาน Google Drive API กับ GWT - person Joe; 26.07.2013
comment
ดูเหมือนว่าแหล่งที่มาของ Dropbox กำลังใช้คลาส URL ของ Java ซึ่งเปลี่ยนแปลงบน GAE ฉันคิดว่าฉันอาจจะสามารถแก้ไขแหล่งที่มาของ Dropbox เพื่อแก้ไขปัญหานี้ได้ แต่ฉันไม่แน่ใจ มีความคิดอะไรบ้าง? - person Joe; 26.07.2013
comment
ตั้งแต่เวอร์ชัน 2.0.5 ของ Dropbox SDK สำหรับ Java คุณสามารถใช้ GoogleAppEngineHttpRequestor ซึ่งมีการสนับสนุนอย่างชัดเจนสำหรับ URL Fetch API ของ App Engine - person Greg; 13.06.2016

Dropbox SDK ล่าสุดให้คุณเลือกการใช้งาน HttpRequestor

new DbxRequestConfig(APP_NAME, userLocale, HttpRequestor);

ดังนั้นสิ่งที่คุณต้องทำคือปรับ com.dropbox.core.http.StandardHttpRequestor ให้เป็นมิตรกับ Appengine

สรุปสาระสำคัญ: 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);

ดังนั้นการใช้ Proxy (ไฟร์วอลล์ของฉัน) ใน StandardHttpRequestor และการใช้ผู้ร้องขอนี้ใน DbxRequestConfig มันได้ผลสำหรับฉัน

person Sharad    schedule 31.10.2013

ฉันก็ประสบปัญหาเดียวกันเช่นกัน ตามโพสต์นี้ https://groups.google.com/forum/#!topic/google-appengine-java/V8pREOXPX24,

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

ดังนั้นฉันจึงเปลี่ยนชั้นเรียน

javax.net.ssl.HttpsURLConnection

by

java.net.HttpURLConnection 

ในคลาส com.dropbox.core.http.StandardHttpRequestor และสร้าง Dropbox Java SDK ขึ้นมาใหม่ มันทำงานได้ดี ตัวอย่างแอปที่ใช้งานได้ที่ https://gwt-gae-testing.appspot.com/

person user2489475    schedule 24.08.2013

นี่เป็นวิธีเดียวที่จะดึงข้อมูล access_token (แต่ฉันไม่รู้วิธีจัดการกับวิธีอื่นของ 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();
}

ฉันขอแนะนำให้เปลี่ยน HttpRequestor ตามที่ @radu-c กล่าว มันทำงานได้ดี

person Aerox    schedule 23.05.2014