การเชื่อมต่อ http ระหว่างแอปเพล็ต Java และเซิร์ฟเวอร์ django สำหรับการร้องขอการโพสต์

ฉันกำลังพยายามส่งข้อมูลการบันทึกจากแอปเพล็ตการสแกนเอกสารไปยังเว็บเซิร์ฟเวอร์ที่ขับเคลื่อนด้วย django

ฉันกำลังทดสอบโดยใช้เว็บเซิร์ฟเวอร์ของ django เอง ฉันได้สร้างคำขอ POST แบบง่าย ๆ ด้วย java แต่เซิร์ฟเวอร์ django กำลังส่งข้อผิดพลาด 500 ฉันไม่สามารถรับข้อมูลใดๆ เกี่ยวกับข้อผิดพลาดได้ ดูเหมือนว่าฉันจะใช้ pydevd เพื่อทำลายโค้ดในมุมมอง django ของฉันไม่ได้ (URL ของฉันได้รับการตั้งค่าอย่างถูกต้อง - ฉันสามารถอ่านโค้ดได้หากไปที่ URL ด้วยเบราว์เซอร์) ฉันไม่มีการตั้งค่าการดีบักในแอปเพล็ต แต่มีข้อมูลมากมายที่จะไปที่คอนโซล ฉันรู้ว่า django ส่งข้อมูล html จำนวนมากพร้อมกับข้อผิดพลาด 500 แต่แอปเพล็ต java ของฉันกำลังส่งข้อยกเว้น (เพื่อตอบสนองต่อข้อผิดพลาด 500) ก่อนที่จะสามารถอ่านข้อความได้

นี่คือรหัสในแอปเพล็ตของฉัน -

private boolean log(String scanURL) {

    try {
        String data = "log=" + buffer.toString();
        URL url = new URL(scanURL);
        URLConnection conn = url.openConnection();
        conn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
        writer.write(data);
        writer.flush();

        // Handle the response
        int responseCode = ((HttpURLConnection) conn).getResponseCode();
        addItem("Http response code " + new Integer(responseCode).toString());
        addItem("creating BufferedReader");
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;
        addItem("reading response");
        while ((line = reader.readLine()) != null) {
            addItem(line);
        }
        addItem("Closing Writer");
        writer.close();
        addItem("Closing Reader");
        reader.close();

        if (responseCode == 200) {
            return true;
            }
        else {
            return false;
        }

    } catch (Exception e) {
        addItem("Error - writing to log failed. " + e);
        return false;
    }

}

และมุมมอง django ของฉันคือ -

from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from cache.shortcuts import permission_required

@login_required
@permission_required('documents.add_documentindex', raise_exception=True)
def save_log(request):
    import pydevd;pydevd.settrace()
    log_text = request.POST['log']
    with open("scanning.log", "a") as f:
        f.write(log_text)
    return HttpResponse('ok')

ฉันสงสัยว่าฉันต้องทำงานบางอย่างกับส่วนหัว http แต่ถ้าไม่มีข้อมูลเพิ่มเติมอีกเล็กน้อยจาก django ความรู้ของฉันเกี่ยวกับ http ก็เป็นอุปสรรคอย่างมาก

ข้อเสนอแนะใด ๆ ในการทำให้สิ่งนี้ใช้งานได้หรือแม้แต่รับข้อมูลเพิ่มเติมเล็กน้อยเกี่ยวกับข้อผิดพลาดเซิร์ฟเวอร์ 500 ของ django จะได้รับการชื่นชมอย่างมาก!

อัปเดต stacktrace จากข้อยกเว้น Java เป็นดังนี้

java.io.IOException: Server returned HTTP response code: 500 for URL: http://10.0.0.68:8000/scanning_log
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection$6.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.net.www.protocol.http.HttpURLConnection.getChainedException(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at co.altcom.cache.scanner.CacheScan.log(CacheScan.java:408)
    at co.altcom.cache.scanner.CacheScan.createLog(CacheScan.java:385)
    at co.altcom.cache.scanner.CacheScan.destroy(CacheScan.java:70)
    at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.io.IOException: Server returned HTTP response code: 500 for URL: http://10.0.0.68:8000/scanning_log
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at java.net.HttpURLConnection.getResponseCode(Unknown Source)
    at co.altcom.cache.scanner.CacheScan.log(CacheScan.java:405)
    ... 4 more

person Aidan Ewen    schedule 29.08.2012    source แหล่งที่มา
comment
"Error - writing to log failed." + e เอ่อ?.. แกล้งทำเป็นว่าเราไม่ได้กำลังดูคอมพิวเตอร์ของคุณและลองเพิ่ม e.printStackTrace(); และคัดลอก/วางเอาต์พุต   -  person Andrew Thompson    schedule 29.08.2012
comment
ขอบคุณแอนดรูว์ ฉันได้เพิ่มการติดตามสแต็กแล้ว อาจเป็นของจากเซิร์ฟเวอร์ที่ฉันสนใจมากกว่า - ดูเหมือนว่าข้อยกเว้นนั้นจะถูกส่งออกมาเพื่อตอบสนองต่อข้อผิดพลาด 500 เสมอ ฉันจำเป็นต้องรู้ว่าเหตุใดจึงเกิดข้อผิดพลาด 500 บางทีฉันอาจต้องการทางเลือกอื่นแทน getInputStream ซึ่งจะยังคงดูสตรีมอินพุตโดยไม่มีข้อยกเว้นในการตอบสนอง 500   -  person Aidan Ewen    schedule 29.08.2012
comment
conn.getInputStream() ล้มเหลว แต่ conn.getErrorStream() ส่งคืนเอาต์พุตที่ฉันต้องการจากเซิร์ฟเวอร์ (ขอบคุณ stackoverflow.com/questions/3432263/)   -  person Aidan Ewen    schedule 29.08.2012
comment
ทุกสิ่งเช่น creating BufferedReader - มันปรากฏที่ไหนกันแน่? บรรทัดที่ 405 ของ CacheScan.java คืออะไร   -  person Andrew Thompson    schedule 29.08.2012
comment
มันล้มเหลวใน BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); โดยเฉพาะมันล้มเหลวใน conn.getInputStream() ตอนนี้ฉันได้อัปเดตโค้ดแล้วดังนั้นจึงไม่ล้มเหลวอีกต่อไป (ดูความคิดเห็นด้านบน) อย่างไรก็ตามคอนโซล Java ขัดข้องพร้อมข้อความเกี่ยวกับ 'Thread death' หรือบางอย่าง (และหายไปก่อนที่ฉันจะสามารถรับข้อมูลเพิ่มเติมได้ - มันทำให้เซิร์ฟเวอร์ของฉันขัดข้องในกระบวนการนี้!) ฉันจะอัปเดตเมื่อฉันได้รับข้อมูลเพิ่มเติม   -  person Aidan Ewen    schedule 29.08.2012
comment
เซิร์ฟเวอร์ขัดข้องของฉันให้การติดตามสแต็กเดียวกันกับข้อผิดพลาดของ Python แบบเปิด - bugs.python.org/issue14574 (ยังคงไม่ได้รับข้อมูลเกี่ยวกับฝั่งจาวา) เริ่มสงสัยว่ารูกระต่ายนั้นลึกแค่ไหน - คิดว่าฉันต้องออกไปแล้วอ่านเรื่อง http และการเขียนโปรแกรมซ็อกเก็ตสักหน่อย   -  person Aidan Ewen    schedule 29.08.2012
comment
ดูเหมือนว่าเซิร์ฟเวอร์ล่มเกิดจากการเรียกใช้โค้ดการเชื่อมต่อ http ในแอปเพล็ตหยุดหรือทำลายวิธีการ ฉันคิดว่าการเชื่อมต่อขาดหายไปและนั่นคือสิ่งที่ทำให้เซิร์ฟเวอร์ python หยุดทำงาน การเรียกใช้การเชื่อมต่อภายนอกวิธีการหยุดหรือทำลายช่วยแก้ไขปัญหาได้   -  person Aidan Ewen    schedule 30.08.2012


คำตอบ (1)


คำถามเดิมของฉันขอคำแนะนำเพื่อรับข้อมูลเพิ่มเติมจากเซิร์ฟเวอร์ django ฉันเดาว่าคำตอบที่ฉันต้องการนั้นพบได้ที่ java.io.IOException: เซิร์ฟเวอร์ส่งคืนรหัสตอบกลับ HTTP: 500

วิธีการ getInputStream ของ Java ของวัตถุ URLConnection จะส่งข้อยกเว้นเมื่อเซิร์ฟเวอร์ส่งคืนรหัสข้อผิดพลาด (เช่น 500) วิธีแก้ไขคือใช้ getErrorStream แทน สิ่งนี้ทำให้ฉันสามารถเข้าถึงข้อมูลข้อผิดพลาด html ที่สร้างโดยเซิร์ฟเวอร์ของ django

รหัสการทำงานสุดท้ายสำหรับวิธีการบันทึกแอปเพล็ตของฉันคือ -

public boolean log(String logURL) {

    String charset = "UTF-8";
    String logData = logBuffer.toString();
    OutputStream output = null;
    HttpURLConnection conn = null;
    BufferedReader reader = null;
    InputStream in = null;

    try {
        String query = String.format("log=%s", URLEncoder.encode(logData, charset));
        conn = (HttpURLConnection) new URL(logURL).openConnection();
        conn.setDoOutput(true);
        conn.setRequestProperty("Accept-Charset", charset);
        conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=" + charset);
        output = conn.getOutputStream();
        output.write(query.getBytes(charset));

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        return false;
    } catch (MalformedURLException e) {
        e.printStackTrace();
        return false;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    } finally {
         if (output != null) try { output.close(); } catch (IOException e) {e.printStackTrace();}
    }

    // Handle the response
    try {
        int responseCode = conn.getResponseCode();
        if (responseCode == 200) {
            in = conn.getInputStream();
        } else {
            in = conn.getErrorStream();
        }
        reader = new BufferedReader(new InputStreamReader(in));
        String line;
        logNote("reading response");
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        reader.close();         
        if (responseCode == 200) {
            return true;
            }
        else {
            return false;
        }

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        return false;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    } finally {
        if (reader != null) try { reader.close(); } catch (IOException e) {e.printStackTrace();}
    }   
}

การใช้ java.net.URLConnection เพื่อเริ่มทำงาน และจัดการคำขอ HTTP มีข้อมูลที่เป็นประโยชน์มาก

หวังว่านี่จะเป็นประโยชน์สำหรับคนอื่น

person Aidan Ewen    schedule 29.08.2012