java.net.ProtocolException:意外的状态行:HTTP /1.1422 UnprocessableEntity

loe*_*chg 3 android retrofit okhttp

我正在使用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
Run Code Online (Sandbox Code Playgroud)

使用以下库:

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'
Run Code Online (Sandbox Code Playgroud)

我期待以下内容回来(故意测试422错误):

{
    "title": [
        "is too short (minimum is 6 characters)"
    ]
}
Run Code Online (Sandbox Code Playgroud)

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

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

render json: @post.errors.to_json, status: :unprocessable_entity
Run Code Online (Sandbox Code Playgroud)

另一个编辑:

这是通过Wireshark发出的请求的屏幕截图.没有什么看起来与众不同,但我以前从未使用过该工具.

总体

这是适当的十六进制.

十六进制

Jak*_*ton 7

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

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

status-line = HTTP-version SP status-code SP reason-phrase CRLF
Run Code Online (Sandbox Code Playgroud)

从例外情况看,非空格字符(或两个)位于状态代码和原因短语之间.

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