ฉันจะรับเนื้อหาการตอบสนอง http เป็นสตริงใน Java ได้อย่างไร


155

ฉันรู้ว่าเคยมีวิธีที่จะได้รับกับ apache คอมมอนส์เป็นเอกสารที่นี่: http://hc.apache.org/httpclient-legacy/apidocs/org/apache/commons/httpclient/HttpMethod.html และตัวอย่างที่นี่:

http://www.kodejava.org/examples/416.html

แต่ฉันเชื่อว่านี่เลิกใช้แล้ว มีวิธีอื่นที่จะทำให้ http ได้รับการร้องขอใน java และรับเนื้อหาการตอบสนองเป็นสตริงและไม่กระแส?


1
เนื่องจากคำถามและคำตอบทั้งหมดดูเหมือนจะเป็นเรื่องเกี่ยวกับไลบรารี Apache ดังนั้นควรติดแท็กเป็นเช่นนี้ ฉันไม่เห็นอะไรเลยหากไม่ใช้ libs บุคคลที่สาม
eis

เกี่ยวข้อง: stackoverflow.com/questions/21574478
tkruse

คำตอบ:


104

ห้องสมุดทุกแห่งที่ฉันนึกถึงจะได้รับกระแส คุณสามารถใช้IOUtils.toString()จากApache Commons IOเพื่ออ่านการInputStreamเรียกใช้แบบStringin one เช่น:

URL url = new URL("http://www.example.com/");
URLConnection con = url.openConnection();
InputStream in = con.getInputStream();
String encoding = con.getContentEncoding();
encoding = encoding == null ? "UTF-8" : encoding;
String body = IOUtils.toString(in, encoding);
System.out.println(body);

อัปเดต:ฉันเปลี่ยนตัวอย่างด้านบนเพื่อใช้การเข้ารหัสเนื้อหาจากการตอบกลับหากมี มิฉะนั้นจะใช้ค่าเริ่มต้นเป็น UTF-8 ซึ่งเป็นการคาดเดาที่ดีที่สุดแทนที่จะใช้ค่าเริ่มต้นของระบบโลคัล


4
สิ่งนี้จะทำให้ข้อความเสียหายในหลาย ๆ กรณีเนื่องจากวิธีการใช้การเข้ารหัสข้อความเริ่มต้นของระบบซึ่งแตกต่างกันไปตามระบบปฏิบัติการและการตั้งค่าผู้ใช้
McDowell

1
@McDowell: อ๊ะขอบคุณฉันเชื่อมโยง javadoc สำหรับวิธีการเข้ารหัส แต่ฉันลืมที่จะใช้มันในตัวอย่าง ฉันเพิ่ม UTF-8 ไปเป็นตัวอย่างในตอนนี้แม้ว่าในทางเทคนิคควรใช้Content-Encodingส่วนหัวจากการตอบกลับหากมี
WhiteFang34

การใช้งานที่ยอดเยี่ยมของ IOUtils วิธีการปฏิบัติที่ดี
Spidey

8
มีการระบุชุดอักขระจริงใน contentType เช่น "charset = ... " แต่ไม่ได้อยู่ใน contentEncoding ซึ่งมีบางอย่างเช่น 'gzip'
Timur Yusupov

1
ฟังก์ชั่นนี้ทำให้ปิดกระแสข้อมูลขาเข้ามีวิธี @ WhiteFang34 ฉันสามารถพิมพ์การตอบสนองของฉันและยังคงใช้เอนทิตี http ต่อไป
amIT

276

นี่คือสองตัวอย่างจากโครงการทำงานของฉัน

  1. การใช้EntityUtilsและHttpEntity

    HttpResponse response = httpClient.execute(new HttpGet(URL));
    HttpEntity entity = response.getEntity();
    String responseString = EntityUtils.toString(entity, "UTF-8");
    System.out.println(responseString);
  2. การใช้ BasicResponseHandler

    HttpResponse response = httpClient.execute(new HttpGet(URL));
    String responseString = new BasicResponseHandler().handleResponse(response);
    System.out.println(responseString);

10
ปัญหาเดียวที่ฉันต้องเผชิญกับวิธีที่ 1 คือวัตถุนิติบุคคลที่มีการบริโภคเมื่อคุณทำและมันอยู่ในขณะนี้response.getEntity() responseStringถ้าคุณพยายามที่จะทำ response.getEntity (ที่) IllegalStateExceptionอีกครั้งก็จะกลับ
Tirtha

ทำงานในกรณีของฉัน - รับร่างกายจากการตอบสนอง CloseableHttpClient
Jaroslav Štreit

1
httpClient คืออะไร!
Andreas L.

1
@AndreasL httpClient เป็นประเภท HttpClient (แพคเกจ org.apache.commons.httpclient)
spideringweb

มันเป็นเรื่องธรรมดาที่จะได้รับเนื้อหาการตอบสนองเป็นสตริงหรืออาร์เรย์ไบต์หรือบางสิ่งบางอย่าง น่าจะดีกับ API โดยตรงบน Entity เพื่อให้สิ่งนั้นกับคุณ ต้องมองหาสิ่งนี้เพื่อหาชั้น util นี้
ซานตาคลอส Ibsen

52

นี่คือตัวอย่างจากโปรเจกต์ง่ายๆที่ฉันใช้ในการใช้ไลบรารี่ httpclient จาก Apache:

String response = new String();
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("j", request));
HttpEntity requestEntity = new UrlEncodedFormEntity(nameValuePairs);

HttpPost httpPost = new HttpPost(mURI);
httpPost.setEntity(requestEntity);
HttpResponse httpResponse = mHttpClient.execute(httpPost);
HttpEntity responseEntity = httpResponse.getEntity();
if(responseEntity!=null) {
    response = EntityUtils.toString(responseEntity);
}

เพียงใช้ EntityUtils เพื่อดึงส่วนการตอบสนองเป็นสตริง ง่ายมาก.


28

นี่ค่อนข้างง่ายในกรณีเฉพาะ แต่ค่อนข้างยุ่งยากในกรณีทั่วไป

HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://stackoverflow.com/");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println(EntityUtils.getContentMimeType(entity));
System.out.println(EntityUtils.getContentCharSet(entity));

คำตอบขึ้นอยู่กับส่วนหัวของการตอบสนองContent-Type HTTP

ส่วนหัวนี้มีข้อมูลเกี่ยวกับเพย์โหลดและอาจกำหนดการเข้ารหัสข้อมูลที่เป็นข้อความ แม้ว่าคุณจะสมมติประเภทข้อความคุณอาจต้องตรวจสอบเนื้อหาเองเพื่อพิจารณาการเข้ารหัสอักขระที่ถูกต้อง เช่นดูข้อมูลจำเพาะ HTML 4สำหรับรายละเอียดเกี่ยวกับวิธีการทำเช่นนั้นสำหรับรูปแบบนั้น ๆ

เมื่อทราบการเข้ารหัสแล้วInputStreamReaderสามารถใช้ในการถอดรหัสข้อมูล

คำตอบนี้ขึ้นอยู่กับเซิร์ฟเวอร์ที่ทำสิ่งที่ถูกต้อง - หากคุณต้องการจัดการกับกรณีที่ส่วนหัวการตอบสนองไม่ตรงกับเอกสารหรือการประกาศเอกสารไม่ตรงกับการเข้ารหัสที่ใช้นั่นคือกาต้มน้ำปลาอีกตัว


วิธีรับเป็น HashMap ฉันได้รับการตอบสนองในฐานะ Json จะอ่านได้อย่างไร?
user1735921

10

ด้านล่างเป็นวิธีง่ายๆในการเข้าถึงการตอบสนองในฐานะ String โดยใช้ Apache HTTP Client Library

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;

//... 

HttpGet get;
HttpClient httpClient;

// initialize variables above

ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpClient.execute(get, responseHandler);


9

คำตอบโดย McDowell นั้นถูกต้อง อย่างไรก็ตามหากคุณลองคำแนะนำอื่น ๆ ในโพสต์ด้านบน

HttpEntity responseEntity = httpResponse.getEntity();
if(responseEntity!=null) {
   response = EntityUtils.toString(responseEntity);
   S.O.P (response);
}

จากนั้นจะให้ผิดกฎหมาย StateException ที่ระบุว่าเนื้อหานั้นถูกใช้ไปแล้ว


3

เราสามารถใช้โค้ดด้านล่างเพื่อรับการตอบกลับ HTML ใน java

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.HttpResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.apache.log4j.Logger;

public static void main(String[] args) throws Exception {
    HttpClient client = new DefaultHttpClient();
    //  args[0] :-  http://hostname:8080/abc/xyz/CheckResponse
    HttpGet request1 = new HttpGet(args[0]);
    HttpResponse response1 = client.execute(request1);
    int code = response1.getStatusLine().getStatusCode();

    try (BufferedReader br = new BufferedReader(new InputStreamReader((response1.getEntity().getContent())));) {
        // Read in all of the post results into a String.
        String output = "";
        Boolean keepGoing = true;
        while (keepGoing) {
            String currentLine = br.readLine();

            if (currentLine == null) {
                keepGoing = false;
            } else {
                output += currentLine;
            }
        }

        System.out.println("Response-->" + output);
    } catch (Exception e) {
        System.out.println("Exception" + e);

    }
}

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

0

นี่เป็นวิธีที่มีน้ำหนักเบาในการทำเช่นนั้น:

String responseString = "";
for (int i = 0; i < response.getEntity().getContentLength(); i++) { 
    responseString +=
    Character.toString((char)response.getEntity().getContent().read()); 
}

ด้วยหลักสูตรresponseStringที่มีการตอบสนองและการตอบสนองของเว็บไซต์ที่เป็นประเภทHttpResponse, ส่งคืนโดยHttpClient.execute(request)


0

ต่อไปนี้เป็นข้อมูลโค้ดที่แสดงวิธีที่ดีกว่าในการจัดการเนื้อหาการตอบสนองเป็นสตริงไม่ว่าจะเป็นการตอบสนองที่ถูกต้องหรือการตอบสนองข้อผิดพลาดสำหรับคำขอ HTTP POST:

BufferedReader reader = null;
OutputStream os = null;
String payload = "";
try {
    URL url1 = new URL("YOUR_URL");
    HttpURLConnection postConnection = (HttpURLConnection) url1.openConnection();
    postConnection.setRequestMethod("POST");
    postConnection.setRequestProperty("Content-Type", "application/json");
    postConnection.setDoOutput(true);
    os = postConnection.getOutputStream();
    os.write(eventContext.getMessage().getPayloadAsString().getBytes());
    os.flush();

    String line;
    try{
        reader = new BufferedReader(new InputStreamReader(postConnection.getInputStream()));
    }
    catch(IOException e){
        if(reader == null)
            reader = new BufferedReader(new InputStreamReader(postConnection.getErrorStream()));
    }
    while ((line = reader.readLine()) != null)
        payload += line.toString();
}       
catch (Exception ex) {
            log.error("Post request Failed with message: " + ex.getMessage(), ex);
} finally {
    try {
        reader.close();
        os.close();
    } catch (IOException e) {
        log.error(e.getMessage(), e);
        return null;
    }
}

0

คุณสามารถใช้ไลบรารีของบุคคลที่สามที่ส่งการร้องขอ Http และจัดการการตอบสนอง หนึ่งในผลิตภัณฑ์ที่รู้จักกันดีจะเป็นคอมมอน Apache HttpClient: HttpClient Javadoc , HttpClient Maven สิ่งประดิษฐ์ มีคือไกลโดยที่รู้จักกันน้อย แต่ง่ายมาก HttpClient (ส่วนหนึ่งของการเปิดแหล่ง MgntUtils ห้องสมุดที่เขียนโดยฉัน): MgntUtils HttpClient Javadoc , MgntUtils Maven สิ่งประดิษฐ์ , MgntUtils Github การใช้ไลบรารีเหล่านี้อย่างใดอย่างหนึ่งคุณสามารถส่งคำขอ REST ของคุณและรับการตอบสนองอย่างอิสระจาก Spring ซึ่งเป็นส่วนหนึ่งของตรรกะทางธุรกิจของคุณ


0

หากคุณกำลังใช้แจ็คสันในการแยกแยะเนื้อหาตอบกลับโซลูชันที่ง่ายที่สุดวิธีหนึ่งคือใช้request.getResponseBodyAsStream()แทนrequest.getResponseBodyAsString()

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.