java.net.ProtocolException:意外状态行:HTTP / 1.1 422Unprocessable实体实体、意外、状态、ProtocolException

由网友(承诺似雾如风)分享简介:我正在使用改造+ Okhttp POST请求,我快到了以下错误: 4月2日至五日:45:13.981 15972-16249 / com.myapp.android D /改造:---> HTTP POST http://10.0.0.4:3000/api/v1/users/1/posts4月2日至5日:45:...

我正在使用改造+ Okhttp POST请求,我快到了以下错误:

  4月2日至五日:45:13.981 15972-16249 / com.myapp.android D /改造:---> HTTP POST http://10.0.0.4:3000/api/v1/users/1/posts4月2日至5日:45:13.981 15972-16249 / com.myapp.android D /改造:接受:应用/ JSON4月2日至5日:45:13.981 15972-16249 / com.myapp.android D /改造:内容类型:应用程序/ JSON的;字符集= UTF-84月2日至5日:45:13.981 15972-16249 / com.myapp.android D /改造:内容长度:1504月2日至5日:45:13.981 15972-16249 / com.myapp.android D /改造: {"description":"test","image_url":"https://s3.amazonaws.com/bucket/xxx-4800-b0e0-fc206f95f158.jpeg","title":"test","price":0.0,"user_id":0}4月2日至5日:45:13.981 15972-16249 / com.myapp.android D /改造:---> END HTTP(150字节体)4月2日至5日:45:14.001 15972-15972 / com.myapp.android W / EGL_genymotion:eglSurfaceAttrib没有实现4月2日至5日:45:14.017 15972-16249 / com.myapp.android D /改造:---- ERROR http://10.0.0.4:3000/api/v1/users/1/posts4月2日至5日:45:14.017 15972-16249 / com.myapp.android D /改造:java.net.ProtocolException:意外状态行:HTTP / 1.1 422Unprocessable实体            在com.squareup.okhttp.internal.http.StatusLine.parse(StatusLine.java:73)            在com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:187)            在com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)            在com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:791)            在com.squareup.okhttp.internal.http.HttpEngine.access $ 200(HttpEngine.java:90)            在com.squareup.okhttp.internal.http.HttpEngine $ NetworkInterceptorChain.proceed(HttpEngine.java:784)            在com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:645)            在com.squareup.okhttp.Call.getResponse(Call.java:263)            在com.squareup.okhttp.Call $ ApplicationInterceptorChain.proceed(Call.java:219)            在com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:192)            在com.squareup.okhttp.Call.execute(Call.java:79)            在retrofit.client.OkClient.execute(OkClient.java:53)            在retrofit.RestAdapter $ RestHandler.invokeRequest(RestAdapter.java:326)            在retrofit.RestAdapter $ RestHandler.access $ 100(RestAdapter.java:220)            在retrofit.RestAdapter $ RestHandler $ 1.invoke(RestAdapter.java:265)            在retrofit.RxSupport $ 2.run(RxSupport.java:55)            在java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:422)            在java.util.concurrent.FutureTask.run(FutureTask.java:237)            在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)            在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:587)            在retrofit.Platform $的Andr​​oid $ 2 $ 1.run(Platform.java:142)            在java.lang.Thread.run(Thread.java:841)4月2日至5日:45:14.017 15972-16249 / com.myapp.android D /改造:---- END错误 

使用以下库

 编译com.squareup.retrofit:改造:1.9.0编译com.squareup.okhttp:okhttp-的URLConnection:2.2.0编译com.squareup.okhttp:okhttp:2.2.0 

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

  {    头衔:[        过短(最短为6个字符)    ]} 
重磅 力软 JAVA 开发平台将于7月20日正式上线

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

编辑:我正在用Rails以下调用返回这个结果是422:

 渲染JSON:@ post.errors.to_json,状态:unprocessable_entity 

另一个编辑:

下面的请求的截图被Wireshark的通过做出。看起来没有什么与众不同的,但我也从来没有使用过的工具。

下面是相应的十六进制。

解决方案

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

  

的响应消息的第一行是状态线,由  的协议版本,一个空格(SP),状态code,另一  的空间,可能是空的文本短语描述状态code,  与CRLF结束。

 状态行= http版本SP状态 -  code SP原因短语CRLF 

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

OkHttp正在寻找这些元素之间的ASCII空格(字符#32)。您可以使用类似的是Wireshark或者查尔斯拦截网络流量,找出正在使用的字符由HTTP服务器。

I'm making a POST request using Retrofit + Okhttp, and I'm running into the following error:

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

Using the following libs:

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'

I'm expecting something like the following to come back (intentionally testing a 422 error):

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

I get the expected result when sending via Postman (https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en)

Edit: I'm making the following call in Rails to return this 422 result:

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

Another Edit:

Here's a screenshot of the request being made via Wireshark. Nothing looks out of the ordinary, but I've also never used the tool before.

Here's the appropriate hex.

解决方案

Your server appears to violate the HTTP spec. The status line is defined as follows:

The first line of a response message is the status-line, consisting of the protocol version, a space (SP), the status code, another space, a possibly empty textual phrase describing the status code, and ending with CRLF.

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

From the exception it appears that a non-space character (or two) is between the status code and reason phrase.

OkHttp is looking for ASCII spaces (character #32) between these elements. You can use something like WireShark or maybe Charles to intercept the network traffic and figure out what characters are being used by your HTTP server.

阅读全文

相关推荐

最新文章