如何获得 HTTP 响应正文作为字符串?

我知道过去有一种方法可以使用 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 请求,并以字符串而不是流的形式获取响应主体?

573579 次浏览

我能想到的每个库都会返回一条流。您可以使用来自 Apache Commons IOIOUtils.toString()在一个方法调用中将 InputStream读入 String。例如:

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作为最佳猜测,而不是使用本地系统默认值。

这在特定情况下相对简单,但在一般情况下相当棘手。

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 响应头

此头包含有效负载的信息,也许吧定义文本数据的编码。即使你假设是 文字类型,你也可能需要检查内容本身来确定正确的字符编码。例如,有关如何为特定格式实现这一点的详细信息,请参阅 < a href = “ http://www.w3.org/TR/html4/charset.HTML # h-5.2.2”rel = “ noReferrer”> HTML 4 spec 。

一旦编码已知,就可以使用 InputStreamReader对数据进行解码。

这个问题的答案取决于服务器是否做了正确的事情——如果您希望处理响应头与文档不匹配或文档声明与所使用的编码不匹配的情况,那就是另一回事了。

下面是我使用 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 抓取响应主体作为一个字符串。非常简单。

不如这样吧?

org.apache.commons.io.IOUtils.toString(new URL("http://www.someurl.com/"));

下面是我的工作项目中的两个例子。

  1. 使用 EntityUtils和 < a href = “ http://hc.apache.org/httpComponent-core-ga/httpcore/apidocs/org/apache/http/HttpEntity.html”> HttpEntity

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

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

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

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

然后,它会给出 illegalStateException,指出内容已经被使用。

下面是使用 ApacheHTTPClient 库以 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);

我们也可以使用下面的代码来获得 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);


}
}

这里有一个轻量级的方法:

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

当然,responseString包含网站的响应和响应类型为 HttpResponse,由 HttpClient.execute(request)返回

下面是代码片段,它展示了将响应主体作为 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;
}
}

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

这是一个普通的 Java 答案:

import java.net.http.HttpClient;
import java.net.http.HttpResponse;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;


...
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(targetUrl)
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
String responseString = (String) response.body();

使用 Apache commons Fluent API,可以按照下面提到的方式完成,

String response = Request.Post("http://www.example.com/")
.body(new StringEntity(strbody))
.addHeader("Accept","application/json")
.addHeader("Content-Type","application/json")
.execute().returnContent().asString();