【问题标题】:How can I get an HTTP response body as a string?如何将 HTTP 响应正文作为字符串获取?
【发布时间】:2011-08-11 19:12:45
【问题描述】:

我知道曾经有一种方法可以通过 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 请求并将响应正文作为字符串而不是流获取吗?

【问题讨论】:

  • 由于问题和所有答案似乎都是关于 apache 库的,因此应该这样标记。如果不使用 3rdparty 库,我什么都看不到。

标签: java apache-httpclient-4.x apache-commons


【解决方案1】:

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

  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);
    

【讨论】:

  • 我在方法 1 中遇到的唯一问题是,当您执行 response.getEntity() 时会消耗实体对象,现在它可以作为 responseString 使用。如果您再次尝试执行 response.getEntity(),它将返回 IllegalStateException
  • 什么是httpClient?!
  • @AndreasL。 httpClient 是 HttpClient 类型( org.apache.commons.httpclient 包)
  • 将响应内容获取为字符串或字节数组之类的东西很常见。如果直接在 Entity 上使用 API 来为您提供这一点,那就太好了。必须寻找这个才能找到这个 util 类。
  • 我投了赞成票。请考虑添加完整的“导入”语句。
【解决方案2】:

我能想到的每个库都返回一个流。您可以在一个方法调用中使用Apache Commons IO 中的IOUtils.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 作为最佳猜测,而不是使用本地系统默认值。

【讨论】:

  • 这在许多情况下会损坏文本,因为该方法使用系统默认文本编码,该编码因操作系统和用户设置而异。
  • @McDowell:哎呀,谢谢,我将方法的 javadoc 与编码相关联,但我忘记在示例中使用它。我现在在示例中添加了 UTF-8,尽管技术上应该使用响应中的 Content-Encoding 标头(如果可用)。
  • IOUtils 的伟大用法。不错的实用方法。
  • 其实 charset 是在 contentType 中指定的,比如 "charset=...",但不是在 contentEncoding 中,它包含类似 'gzip' 之类的东西
  • 这个函数导致输入流被关闭,有没有办法@WhiteFang34我可以打印我的响应并继续使用http实体
【解决方案3】:

这是我正在使用 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 将响应正文作为字符串获取。很简单。

【讨论】:

    【解决方案4】:

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

    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 response header

    此标头包含有关有效负载的信息,可能定义文本数据的编码。即使您假设text types,您也可能需要检查内容本身以确定正确的字符编码。 例如请参阅HTML 4 spec,了解如何针对特定格式执行此操作。

    一旦知道编码,就可以使用InputStreamReader 来解码数据。

    这个答案取决于服务器做正确的事——如果你想处理响应头与文档不匹配的情况,或者文档声明与使用的编码不匹配,那是另一个问题鱼。

    【讨论】:

    • 如何获取 HashMap ?我得到 Json 的响应,如何阅读?
    【解决方案5】:

    以下是使用 Apache HTTP 客户端库以字符串形式访问响应的简单方法。

    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);
    

    【讨论】:

      【解决方案6】:

      麦克道尔的答案是正确的。但是,如果您在上面的几个帖子中尝试其他建议。

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

      然后它会给你非法状态异常说明内容已经被消费。

      【讨论】:

        【解决方案7】:

        就这个怎么样?

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

        【讨论】:

          【解决方案8】:

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

          【讨论】:

          • 这是一个很好的响应,这是我需要显示的,发布数据到服务器后的响应。干得好。
          【解决方案9】:

          这是一种轻量级的方法:

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

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

          【讨论】:

            【解决方案10】:

            以下是代码 sn-p,它显示了将响应正文作为字符串处理的更好方法,无论它是 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;
                }
            }
            

            【讨论】:

              【解决方案11】:

              您可以使用发送 Http 请求并处理响应的 3-d 方库。众所周知的产品之一是 Apache commons HTTPClient:HttpClient javadocHttpClient Maven artifact。有一个鲜为人知但简单得多的 HTTPClient(我编写的开源 MgntUtils 库的一部分):MgntUtils HttpClient javadocMgntUtils maven artifactMgntUtils Github。使用这些库中的任何一个,您都可以发送 REST 请求并独立于 Spring 作为业务逻辑的一部分接收响应

              【讨论】:

                【解决方案12】:

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

                【讨论】:

                  【解决方案13】:

                  这是一个普通的 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();
                  

                  【讨论】:

                    【解决方案14】:

                    使用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();
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2018-05-15
                      • 1970-01-01
                      • 1970-01-01
                      • 2020-07-24
                      • 1970-01-01
                      • 1970-01-01
                      • 2015-08-09
                      • 1970-01-01
                      相关资源
                      最近更新 更多