【问题标题】:java.net.ProtocolException: Unexpected status line: HTTP/1.1 422��Unprocessable Entityjava.net.ProtocolException: Unexpected status line: HTTP/1.1 422��Unprocessable Entity
【发布时间】:2015-02-05 04:52:27
【问题描述】:

我正在使用 Retrofit + Okhttp 发出 POST 请求,但遇到以下错误:

02-05 04:45:13.981  15972-16249/com.myapp.android D/Retrofit﹕ ---> HTTP POST http://10.0.0.4:3000/api/v1/users/1/posts
02-05 04:45:13.981  15972-16249/com.myapp.android D/Retrofit﹕ Accept: application/json
02-05 04:45:13.981  15972-16249/com.myapp.android D/Retrofit﹕ Content-Type: application/json; charset=UTF-8
02-05 04:45:13.981  15972-16249/com.myapp.android D/Retrofit﹕ Content-Length: 150
02-05 04:45:13.981  15972-16249/com.myapp.android D/Retrofit﹕ {"description":"test","image_url":"https://s3.amazonaws.com/bucket/xxx-4800-b0e0-fc206f95f158.jpeg","title":"test","price":0.0,"user_id":0}
02-05 04:45:13.981  15972-16249/com.myapp.android D/Retrofit﹕ ---> END HTTP (150-byte body)
02-05 04:45:14.001  15972-15972/com.myapp.android W/EGL_genymotion﹕ eglSurfaceAttrib not implemented
02-05 04:45:14.017  15972-16249/com.myapp.android D/Retrofit﹕ ---- ERROR http://10.0.0.4:3000/api/v1/users/1/posts
02-05 04:45:14.017  15972-16249/com.myapp.android D/Retrofit﹕ java.net.ProtocolException: Unexpected status line: HTTP/1.1 422��Unprocessable Entity
            at com.squareup.okhttp.internal.http.StatusLine.parse(StatusLine.java:73)
            at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:187)
            at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
            at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:791)
            at com.squareup.okhttp.internal.http.HttpEngine.access$200(HttpEngine.java:90)
            at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:784)
            at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:645)
            at com.squareup.okhttp.Call.getResponse(Call.java:263)
            at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:219)
            at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:192)
            at com.squareup.okhttp.Call.execute(Call.java:79)
            at retrofit.client.OkClient.execute(OkClient.java:53)
            at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
            at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
            at retrofit.RestAdapter$RestHandler$1.invoke(RestAdapter.java:265)
            at retrofit.RxSupport$2.run(RxSupport.java:55)
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at retrofit.Platform$Android$2$1.run(Platform.java:142)
            at java.lang.Thread.run(Thread.java:841)
02-05 04:45:14.017  15972-16249/com.myapp.android D/Retrofit﹕ ---- END ERROR

使用以下库:

compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.2.0'
compile 'com.squareup.okhttp:okhttp:2.2.0'

我预计会出现以下情况(故意测试 422 错误):

{
    "title": [
        "is too short (minimum is 6 characters)"
    ]
}

通过 Postman (https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en) 发送时我得到了预期的结果

编辑: 我在 Rails 中进行以下调用以返回此 422 结果:

render json: @post.errors.to_json, status: :unprocessable_entity

另一个编辑:

这是通过 Wireshark 发出请求的屏幕截图。没有什么不寻常的地方,但我以前也从未使用过该工具。

这是适当的十六进制。

【问题讨论】:

  • 我有同样的错误。你找到解决办法了吗?
  • @savepopulation 不幸的是没有。幸运的是它刚刚开始工作。 ¯\_(ツ)_/¯ 是的...我知道这是一个糟糕的答案,但这是事实:)
  • 当我检查服务器日志时,有一个未处理的异常导致服务器返回无效响应。所以改造得到一个状态行异常。

标签: android retrofit okhttp


【解决方案1】:

您的服务器似乎违反了 HTTP 规范。状态行定义如下:

响应消息的第一行是状态行,包括 协议版本号、空格 (SP)、状态码、另一个 空格,描述状态代码的可能为空的文本短语, 并以 CRLF 结尾。

status-line = HTTP-version SP status-code SP reason-phrase CRLF

从异常看来,状态代码和原因短语之间有一个(或两个)非空格字符。

OkHttp 正在这些元素之间寻找 ASCII 空格(字符 #32)。您可以使用 WireShark 或 Charles 之类的工具来拦截网络流量并找出您的 HTTP 服务器正在使用哪些字符。

【讨论】:

  • 这很奇怪。我没有用 Rails 做任何不寻常的事情(只不过是一个“Hello World”之类的应用程序。我会看看你的建议,看看它是否能说明问题。
  • 是的,我很想知道这里发生了什么。我不认为我以前见过这样的事情。获取这些字符的十六进制值将有助于识别。我最终也可以在 Rails 中探索,但不是现在。
  • 我之前确实看到过这个返回正确。我很难追踪自那以后我所做的更改或将引入哪些变量。我在原始问题中添加了应该生成此响应的代码行。
  • 我已经启动并运行了wireshark。我用更多信息更新了我的问题。
  • 嗯。该十六进制看起来完全合理。该响应是否最终在客户端产生了相同的错误?
猜你喜欢
  • 2016-11-09
  • 2019-04-26
  • 2016-09-22
  • 1970-01-01
  • 2021-12-19
  • 2022-09-30
  • 1970-01-01
  • 2022-08-14
  • 2019-11-18
相关资源
最近更新 更多