Jetty 12如何读取响应体?Jetty10迁移至12的响应读取异常咨询
Jetty 10迁移至Jetty 12:响应内容混含请求头问题修复
问题核心原因
你遇到的AsyncContentListener的onContent方法收到包含响应头的chunk,主要是因为服务端响应构造不符合Jetty 12的规范,或者WebServiceResponse误将响应头写入了输出流。
具体修复方案
1. 校验响应体的纯净性
先排查WebServiceResponse.serve方法,确保它仅将JSON响应体写入bout,没有把HTTP响应头(比如Content-Type字段)错误输出到流中——如果服务端把响应头写到了响应体流里,客户端必然会在内容chunk中收到这些数据。
2. 改用Jetty 12推荐的响应发送API
Jetty 12对响应发送逻辑做了调整,直接调用Response.write需要正确处理回调,更推荐使用上层的sendContent方法来确保响应头和体的分离。修改服务端代码如下:
Charset encoding = Request.getCharset(pRequest); ByteArrayOutputStream bout = new ByteArrayOutputStream(); WebServiceResponse wsr = new WebServiceResponse(new PrintStream(bout, true, encoding.name()), encoding); rootHandler.serve(restRequest, wsr); // 先完成响应头和状态码设置 pResponse.setStatus(wsr.getStatus().httpStatusCode); pResponse.getHeaders().put(HttpHeader.CONTENT_TYPE, wsr.getContentType()); bout.flush(); // 用sendContent发送响应体,自动处理头体分离 pResponse.sendContent(ByteBuffer.wrap(bout.toByteArray()));
3. 客户端Listener的正确使用姿势
确保客户端代码中,响应头的处理放在AsyncContentListener的onHeadersReceived方法,onContent仅处理响应体:
response.getContentListeners().add(new AsyncContentListener() { @Override public void onHeadersReceived(Response response) { // 在此处理响应头,比如获取Content-Type HttpField contentType = response.getHeaders().get(HttpHeader.CONTENT_TYPE); // ... } @Override public void onContent(Response response, ByteBuffer chunk, Callback callback) { // 仅处理响应体内容 try { byte[] content = new byte[chunk.remaining()]; chunk.get(content); // 业务逻辑处理... } finally { callback.succeeded(); // 必须回调告知Jetty处理完成 } } });
关键注意点
Jetty 12严格区分HTTP响应的头和体,sendContent会自动处理响应头的发送时机,避免头体混写。如果坚持使用write方法,必须确保调用前完成所有响应头设置,并且不能传入null作为Callback(当前代码的null回调可能导致逻辑混乱)。
内容的提问来源于stack exchange,提问作者Erik
相关产品推荐
相关产品推荐

