Closed Ruling95 closed 3 weeks ago
paste log here(if you're using Intellij Idea), and you can go where the exception is thrown(Exchange.kt:244) and debug.
I guess this issue was due to inconsistency between your requestbody's contentLength
and its real length.
paste log here(if you're using Intellij Idea), and you can go where the exception is thrown(Exchange.kt:244) and debug. I guess this issue was due to inconsistency between your requestbody's
contentLength
and its real length.
Is my contentLength() method written incorrectly?
package com.tsy.common.utils.okhttp;
@lombok.extern.slf4j.Slf4j
public class OkHttp3TiresomeRequestBody extends okhttp3.RequestBody {
private final okhttp3.MediaType contentType;
private final byte[] content;
private final okio.BufferedSource bs;
public OkHttp3TiresomeRequestBody(okhttp3.MediaType contentType, String content) {
this.contentType = contentType;
this.content = content.getBytes(java.nio.charset.StandardCharsets.UTF_8);
try(java.io.InputStream ism = new java.io.ByteArrayInputStream(this.content)){
this.bs = okio.Okio.buffer(okio.Okio.source(ism));
} catch (java.io.IOException e) {
throw new com.ddll.base.common.exceptions.BaseException("body data reader error");
}
}
@org.jetbrains.annotations.Nullable
@Override
public okhttp3.MediaType contentType() {
return contentType;
}
@Override
public long contentLength() throws java.io.IOException {
return content.length;
}
public okhttp3.RequestBody tiresome() {
return this;
}
public String contentToString() {
return new String(this.content, java.nio.charset.StandardCharsets.UTF_8);
}
@Override
public void writeTo(@org.jetbrains.annotations.NotNull okio.BufferedSink sink) throws java.io.IOException {
sink.writeAll(bs);
}
public okio.BufferedSource source() throws java.io.IOException {
try(java.io.InputStream ism = new java.io.ByteArrayInputStream(content)){
return okio.Okio.buffer(okio.Okio.source(ism));
} catch (java.io.IOException e) {
throw new com.ddll.base.common.exceptions.BaseException("bse body data reader error");
}
}
}
paste log here(if you're using Intellij Idea), and you can go where the exception is thrown(Exchange.kt:244) and debug. I guess this issue was due to inconsistency between your requestbody's
contentLength
and its real length.Is my contentLength() method written incorrectly?
package com.tsy.common.utils.okhttp;
@lombok.extern.slf4j.Slf4j public class OkHttp3TiresomeRequestBody extends okhttp3.RequestBody {
private final okhttp3.MediaType contentType; private final byte[] content; private final okio.BufferedSource bs; public OkHttp3TiresomeRequestBody(okhttp3.MediaType contentType, String content) { this.contentType = contentType; this.content = content.getBytes(java.nio.charset.StandardCharsets.UTF_8); try(java.io.InputStream ism = new java.io.ByteArrayInputStream(this.content)){ this.bs = okio.Okio.buffer(okio.Okio.source(ism)); } catch (java.io.IOException e) { throw new com.ddll.base.common.exceptions.BaseException("body data reader error"); } } @org.jetbrains.annotations.Nullable @Override public okhttp3.MediaType contentType() { return contentType; } @Override public long contentLength() throws java.io.IOException { return content.length; } public okhttp3.RequestBody tiresome() { return this; } public String contentToString() { return new String(this.content, java.nio.charset.StandardCharsets.UTF_8); } @Override public void writeTo(@org.jetbrains.annotations.NotNull okio.BufferedSink sink) throws java.io.IOException { sink.writeAll(bs); } public okio.BufferedSource source() throws java.io.IOException { try(java.io.InputStream ism = new java.io.ByteArrayInputStream(content)){ return okio.Okio.buffer(okio.Okio.source(ism)); } catch (java.io.IOException e) { throw new com.ddll.base.common.exceptions.BaseException("bse body data reader error"); } }
}
sorry, I can't see any problems in your code. I think it's correct. >-; Now, I'm sorry to say that I have no idea why there was a ProtocolException now.
I hope a kind-hearted person can investigate this issue
It would help to have a small repro project.
Does it still fail if you return -1 for contentLength, and avoid encoding the string until writeTo?
I wonder if some threading problem. But without a clean repro it's hard.
@Ruling95 using the provided code you shared, I don't see how this error could happen. Here is my test which is not producing your error :
public class OkHttpTest {
private static final String ENDPOINT = "http://127.0.0.1:8080";
public static void main(String... args) {
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
return chain.proceed(chain.request());
}
}).build();
try {
OkHttp3TiresomeRequestBody requestBody = new OkHttp3TiresomeRequestBody(
MediaType.get("text/plain"),
"鴻鴻\u0000鴻"
);
Request request = new Request.Builder()
.url(ENDPOINT)
.post(requestBody)
.build();
System.out.println("Body Length: "+request.body().contentLength());
try (Response response = client.newCall(request).execute()) {
ResponseBody body = response.body();
System.out.println(body.string());
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
The only way I have to reproduce the error you get, is to modify your contentLength
method. If I was to investigate somewhere, I would check my interceptor, and that the request I provide in chain.proceed()
method is OK. As mentioned, a small project reproducing the issue would help.
@Ruling95 using the provided code you shared, I don't see how this error could happen. Here is my test which is not producing your error :
public class OkHttpTest { private static final String ENDPOINT = "http://127.0.0.1:8080"; public static void main(String... args) { OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new Interceptor() { @NotNull @Override public Response intercept(@NotNull Chain chain) throws IOException { return chain.proceed(chain.request()); } }).build(); try { OkHttp3TiresomeRequestBody requestBody = new OkHttp3TiresomeRequestBody( MediaType.get("text/plain"), "鴻鴻\u0000鴻" ); Request request = new Request.Builder() .url(ENDPOINT) .post(requestBody) .build(); System.out.println("Body Length: "+request.body().contentLength()); try (Response response = client.newCall(request).execute()) { ResponseBody body = response.body(); System.out.println(body.string()); } } catch(Exception e) { e.printStackTrace(); } } }
The only way I have to reproduce the error you get, is to modify your
contentLength
method. If I was to investigate somewhere, I would check my interceptor, and that the request I provide inchain.proceed()
method is OK. As mentioned, a small project reproducing the issue would help.
long length = request.body().contentLength() request body Length:-1
After my testing, this exception did not occur when I commented out the contentLength() method in OkHttp3TiresomeRequestBody. At least it hasn't reappeared yet. I hope it won't appear again in the future
okhttp version: 4.12.0 spring boot version: 2.3.2.RELEASE okhttp config: okhttp3: pool: max-total: 128 max-per-route: 8 max-idle-connection: 8 timeout: keep-alive-duration: 5 connect-timeout: 8000 read-timeout: 20000 write-timeout: 10000
How to solve the problem that the interface responds but cannot read correctly. thank you
error log deatils:
java.net.ProtocolException: unexpected end of stream at okhttp3.internal.connection.Exchange$RequestBodySink.close(Exchange.kt:244) at okio.RealBufferedSink.close(RealBufferedSink.kt:287) at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:63) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201) at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154) at com.ddll.base.common.utils.okhttp.OkHttp3ClientUtils.doService(OkHttp3ClientUtils.java:335) at com.ddll.base.common.utils.okhttp.OkHttp3ClientUtils.executePostBodyNoParse(OkHttp3ClientUtils.java:226) at com.ddll.base.common.utils.okhttp.OkHttp3ClientUtils.executeNoParse(OkHttp3ClientUtils.java:47) at com.ddll.base.common.utils.okhttp.OkHttp3ClientUtils.execute(OkHttp3ClientUtils.java:23) at com.ddll.channel.ctrip.impl.biz.Okhttp3DockingHttpServiceImpl.okhttp3request(Okhttp3DockingHttpServiceImpl.java:237) at com.ddll.channel.ctrip.impl.biz.Okhttp3DockingHttpServiceImpl.invNotify(Okhttp3DockingHttpServiceImpl.java:181) at com.ddll.channel.ctrip.impl.biz.Okhttp3DockingHttpServiceImpl$$FastClassBySpringCGLIB$$35912cd6.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
at com.ddll.base.common.config.aspects.BizSystemLogAspect.serviceLog(BizSystemLogAspect.java:74)
at sun.reflect.GeneratedMethodAccessor344.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at com.ddll.channel.ctrip.impl.biz.Okhttp3DockingHttpServiceImpl$$EnhancerBySpringCGLIB$$35b17fd0.invNotify()
at com.ddll.channel.ctrip.impl.manager.GrandstandDruckmannSupportManager.retryPush(GrandstandDruckmannSupportManager.java:309)
at com.ddll.channel.ctrip.impl.manager.GrandstandDruckmannSupportManager.inventarDemirDrucken(GrandstandDruckmannSupportManager.java:236)
at com.ddll.channel.ctrip.mq.GeschaftInvNotifyConsumer.onMessage(GeschaftInvNotifyConsumer.java:44)
at com.ddll.channel.ctrip.mq.GeschaftInvNotifyConsumer.onMessage(GeschaftInvNotifyConsumer.java:8)
at com.ddll.channel.ctrip.mq.GeschaftInvNotifyConsumer$$FastClassBySpringCGLIB$$17214543.invoke()
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
at com.ddll.base.common.config.aspects.MQLogAspect.log(MQLogAspect.java:58)
at sun.reflect.GeneratedMethodAccessor316.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
at com.ddll.base.common.config.aspects.MQSimpleIdempotentAspect.handleIdempotent(MQSimpleIdempotentAspect.java:67)
at sun.reflect.GeneratedMethodAccessor315.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at com.ddll.channel.ctrip.mq.GeschaftInvNotifyConsumer$$EnhancerBySpringCGLIB$$9f4efda7.onMessage()
at org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer.handleMessage(DefaultRocketMQListenerContainer.java:394)
at org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer.access$100(DefaultRocketMQListenerContainer.java:70)
at org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer$DefaultMessageListenerConcurrently.consumeMessage(DefaultRocketMQListenerContainer.java:354)
at org.apache.rocketmq.client.impl.consumer.ConsumeMessageConcurrentlyService$ConsumeRequest.run(ConsumeMessageConcurrentlyService.java:402)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Suppressed: okhttp3.internal.http2.StreamResetException: stream was reset: REFUSED_STREAM
at okhttp3.internal.http2.Http2Stream.takeHeaders(Http2Stream.kt:148)
at okhttp3.internal.http2.Http2ExchangeCodec.readResponseHeaders(Http2ExchangeCodec.kt:97)
at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.kt:110)
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:93)
... 80 common frames omitted