【问题标题】:Why am I getting an IllegalArgumentException when calling DELETE over HTTPS but not when using HTTP and not when calling GET over HTTPS?为什么我在通过 HTTPS 调用 DELETE 时收到 IllegalArgumentException,但在使用 HTTP 时却没有,而在通过 HTTPS 调用 GET 时却没有?
【发布时间】:2017-04-24 03:26:59
【问题描述】:

对此问题的任何想法将不胜感激。

我正在使用 Jersey 2.24.1 客户端访问 Play Framework 服务器的 REST API。一般来说,我可以很好地访问大多数 API 端点(GET、POST、PUT)(或者看起来如此):

Response response = ClientBuilder.newClient().target("https://api.myserver.com")
                                .path("/getEndpointPath")
                                .request()
                                .header(HttpHeaders.AUTHORIZATION, "encoded auth string")
                                .get();

但是,使用 HTTPS 时调用 DELETE 方法会抛出异常,但如果将 url 更改为使用 HTTP,则不会异常失败:

Response response = ClientBuilder.newClient().target("https://api.myserver.com")
                                .path("/deleteEndpointPath")
                                .request()
                                .header(HttpHeaders.AUTHORIZATION, "encoded auth string")
                                .delete();

堆栈跟踪:

javax.ws.rs.ProcessingException: java.lang.IllegalArgumentException: protocol = https host = null

    at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:261)
    at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:684)
    at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:681)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
    at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:681)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:411)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.delete(JerseyInvocation.java:360)
    at com.signifyd.integrationTest.v2api.HttpsTest.troubleshootDelete(HttpsTest.java:52)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at com.intellij.junit4.JUnit4TestRunnerUtil$IgnoreIgnoredTestJUnit4ClassRunner.runChild(JUnit4TestRunnerUtil.java:365)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: protocol = https host = null
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1455)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
    at sun.net.www.protocol.http.HttpURLConnection.getHeaderField(HttpURLConnection.java:2979)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:489)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
    at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:399)
    at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
    at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:252)
    ... 36 more
Caused by: java.lang.IllegalArgumentException: protocol = https host = null
    at sun.net.spi.DefaultProxySelector.select(DefaultProxySelector.java:176)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1099)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:999)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:177)
    at sun.net.www.protocol.http.HttpURLConnection.followRedirect0(HttpURLConnection.java:2662)
    at sun.net.www.protocol.http.HttpURLConnection.followRedirect(HttpURLConnection.java:2584)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1770)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
    ... 40 more

另外,我可以使用 Postman 通过 HTTPS 访问这些端点,因此看来这些端点并未完全损坏。

知道这是怎么发生的吗?

其他信息

请求头看起来像:

INFO: 1 * Sending client request on thread main
1 > DELETE https://api.myserver.com/deleteEndpointPath
1 > Authorization: Basic THSAHASDFJalkasdlgjisadjkladfsk09A==:

【问题讨论】:

  • 堆栈跟踪的底部表明正在进行重定向。是否可以记录从 Play Framework 服务器发送的响应?此外,this old Java bug 上的第二条评论还表明,轻微损坏的重定向(Play 可能会生成)可能会导致问题,并且其他客户端可能更能容忍此类损坏的 URL。
  • 您可以发布请求和响应标头吗?
  • @stringy05 我正在寻找一种捕获标题的好方法。我安装了 LoggingFeature 但它没有报告相关调用的标题。
  • @LukeWoodward 您引用的 java 错误可能是问题所在。我检查了播放更改日志,发现以下redirect bug。不幸的是,服务器使用 2.2.x,可能的修复出现在 2.5.5
  • 添加其中之一以让 Jersey 记录 reqs/resp 标头:client.register(new LoggingFilter(java.util.logging.Logger.getAnonymousLogger(), true));

标签: java jersey-2.0 jersey-client


【解决方案1】:

我遇到了这个问题,这是一个简单的错误,把它留在这里以防它帮助其他人。 在下面的代码中,我省略了@PathVariable (value = "id")。现在它包含了以下作品。

@DeleteMapping("/deletePosition/{id}")
public ResponseEntity<?> deletePositionById(@PathVariable (value = "id") Long positionId) {
    return positionService.deletePositionById(positionId);
    
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2016-08-02
    • 1970-01-01
    相关资源
    最近更新 更多