如何在Java中将http响应正文作为字符串获取?


155

我知道曾经有一种使用apache commons来获取它的方法,如此处所述:http : //hc.apache.org/httpclient-legacy/apidocs/org/apache/commons/httpclient/HttpMethod.html 以及此处的示例:

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

但我认为这已被弃用。还有什么其他方法可以在Java中发出http get请求并以字符串而不是流的形式获取响应正文?


1
由于问题和所有答案似乎都与apache库有关,因此应将其标记为apache库。如果不使用3rdparty库,我什么也看不到。
eis 2016年

Answers:


104

我能想到的每个库都返回一个流。你可以使用IOUtils.toString()Apache的百科全书IO读取一个InputStreamString一个方法调用。例如:

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响应中的标头(如果有)。
2011年

IOUtils的大量用法。好的实用方法。
Spidey

8
实际上,charset是在contentType中指定的,例如“ charset = ...”,但未在contentEncoding中指定,后者包含类似“ gzip”的内容
Timur Yusupov 2012年

1
此函数导致输入流被关闭,有没有办法@ WhiteFang34我可以打印我的响应并继续使用http实体
amIT

274

这是我的工作项目中的两个示例。

  1. 使用EntityUtilsHttpEntity

    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'16

1
什么是httpClient ?!
Andreas L.

1
@AndreasL。httpClient类型为HttpClient(org.apache.commons.httpclient程序包)
spideringweb

以字符串或字节数组之类的形式获取响应内容非常普遍。直接在Entity上使用API​​可以达到目的。必须寻找这个才能找到这个util类。
克劳斯·易卜生

52

这是我正在使用来自Apache的httpclient库的另一个简单项目的示例:

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

以下是使用Apache HTTP Client库以String形式访问响应的简单方法。

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

麦克道威尔的答案是正确的。但是,如果您在上面的几篇文章中尝试其他建议。

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

然后,它将向您提供llegalStateException,表明内容已被使用。


3

我们还可以使用以下代码来获取Java中的HTML响应

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 '18年

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

以下是代码片段,它显示了将响应正文作为String处理的更好方法,无论它是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

您可以使用3D方库来发送Http请求并处理响应。其中一种著名的产品是Apache Commons HTTPClient:HttpClient javadocHttpClient Maven构件。到目前为止,鲜为人知但更简单的HTTPClient(我编写的开源MgntUtils库的一部分):MgntUtils HttpClient javadocMgntUtils maven构件MgntUtils Github。使用这些库中的任何一个,您都可以独立于Spring发送REST请求并接收响应,这是业务逻辑的一部分


0

如果您正在使用Jackson来反序列化响应正文,则一种非常简单的解决方案是使用request.getResponseBodyAsStream()而不是request.getResponseBodyAsString()

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.