1

我正在尝试调用一个返回 100 作为响应代码和空响应的 API。

import org.apache.http.client.methods.HttpHead;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.net.URI;

public class SampleController {

    public static void main(String[] args) throws Exception {

        try {
            String urlStr = "http://localhost:8080/headrequest";
            HttpHead request = new HttpHead(new URI(urlStr));
            request.addHeader("Expect", "100-continue");

            CloseableHttpClient client = HttpClients.createDefault();
            client.execute(request);
        } catch (Exception e) {
            System.out.println("Exception: " + e.getMessage());
            throw e;
        }
    }
}

以下是错误:

INFO: I/O exception (org.apache.http.NoHttpResponseException) caught when processing request to {}->http://localhost:8080: The target server failed to respond
Aug 19, 2020 3:36:26 PM org.apache.http.impl.execchain.RetryExec execute
INFO: Retrying request to {}->http://localhost:8080
Aug 19, 2020 3:36:26 PM org.apache.http.impl.execchain.RetryExec execute
INFO: I/O exception (org.apache.http.NoHttpResponseException) caught when processing request to {}->http://localhost:8080: The target server failed to respond
Aug 19, 2020 3:36:26 PM org.apache.http.impl.execchain.RetryExec execute
INFO: Retrying request to {}->http://localhost:8080
Aug 19, 2020 3:36:26 PM org.apache.http.impl.execchain.RetryExec execute
INFO: I/O exception (org.apache.http.NoHttpResponseException) caught when processing request to {}->http://localhost:8080: The target server failed to respond
Aug 19, 2020 3:36:26 PM org.apache.http.impl.execchain.RetryExec execute
INFO: Retrying request to {}->http://localhost:8080
Exception in thread "main" org.apache.http.NoHttpResponseException: localhost:8080 failed to respond
Exception: localhost:8080 failed to respond
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:141)
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
    at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
    at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157)
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
    at com.application.controller.SampleController.main(SampleController.java:20)

但是从服务器访问日志。我可以确认 API 已经执行并且服务器返回了 100 响应代码。

"HEAD /headrequest HTTP/1.1" 100

因此,从上述错误中,我了解到 apaches HttpClinet 未配置为在服务器发送响应代码100并仍期望服务器发送响应后终止连接。

我的问题是,一旦收到 100,是否有任何 java 库可以处理 HEAD 请求的终止。

我确实尝试过谷歌搜索,但未能确定任何解决方案:(

编辑1: 我试过HttpURLConnection

private static void testing() throws Exception {
        HttpURLConnection urlConn = null;

        try {
            String urlStr = "http://localhost:8080/headrequest";

            URL url = new URL(urlStr);
            urlConn = (HttpURLConnection) url.openConnection();
            urlConn.setRequestMethod("HEAD");

            
            urlConn.setRequestProperty("Expect", "100-continue");

            if (urlConn.getResponseCode() != 100) {
                System.out.println("Miss match in the response: " + urlConn.getResponseCode());
            }

        } catch (Exception e) {
            System.out.println("Exception: " + e.getMessage());
            throw e;
        }
    }

以下是错误响应:

Exception: Unexpected end of file from server
Exception in thread "main" java.net.SocketException: Unexpected end of file from server
    at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:851)
    at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:877)
    at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:877)
    at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678)
    at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:848)
    at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:877)
    at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:877)
    at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1593)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1498)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
    at com.application.controller.SampleController.testing(SampleController.java:44)
    at com.application.controller.SampleController.main(SampleController.java:28)
4

1 回答 1

2

RFC7231

客户端不得在不包含消息正文的请求中生成 100-continue 期望。

因此,它可能期望在收到 100 个响应后发送消息正文的 appacheclient,在连接关闭时抛出异常。

如果不是强制使用 apacheclient,下面的简单代码将只读取带有 100 状态代码的响应行并关闭连接。

import java.io.*;
import java.net.*;
class Requestor
{
    public static void main(String args[])
    {
        Socket s;
        BufferedReader br;
        BufferedWriter bw;
        String a;
        String response;
        try{
        s=new Socket("localhost",8080);
        br=new BufferedReader(new InputStreamReader(new BufferedInputStream(s.getInputStream())));
        bw=new BufferedWriter(new OutputStreamWriter(new BufferedOutputStream(s.getOutputStream())));

        bw.write("HEAD /headrequest HTTP/1.1");
        bw.newLine();
        bw.newLine();
        bw.flush();
        response="";
        
        a=br.readLine();
        System.out.println(a);
        
        s.close();
        
        }
        catch(Exception e)
        {
            System.out.println(e);
        }
    }
}
于 2020-08-19T11:57:45.940 回答