You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WireMock处理SOAP MTOM带附件请求报Buffer size exceeded错误

SOAP MTOM + WireMock 请求报IO异常问题

问题相关代码

@Test
public void AfpToPdf() throws Exception {
    stubWireMock(FOLDER_PATH, "convertAfpToPdf", 200, RECUPERA_DOCUMENTO_FOLDER_RESPONSE_OK);
    ConvertAfpToPdfType request = createDocumentoAFPRequest();

    Testata testata = new Testata();

    ConvertAfpToPdfResponseType response = getPortNew().convertAfpToPdf(request, testata, new Holder<>());

    assertNotNull(response);
}


private ConvertAfpToPdfType createDocumentoAFPRequest() {
    ConvertAfpToPdfType request = new ConvertAfpToPdfType();
    ListaFileAfpType listaFileAfpType = new ListaFileAfpType();
    DataHandler dataHandlerAFP = new DataHandler(new FileDataSource("FOLD14.R00407A.NT01.D130606.AFP"));
    listaFileAfpType.setDocumentFileAfp(dataHandlerAFP);
    request.setListaFileAfp(listaFileAfpType);

    return request;

}

protected void stubWireMock(String urlPath, String requestContained, int httpStatus, String bodyFileName) {
    wireMockRule.stubFor(post(urlPathEqualTo((BASE_URL_CONVERSIONE)))
            .withRequestBody(containing("conversioneAfp"))
            .willReturn(
                    aResponse()
                            .withStatus(200)
                            .withHeader("Content-Type", "multipart/form-data")
                            .withBody("prova")));
}

异常堆栈

java.io.IOException: Buffer size exceeded: no line terminator
    at org.eclipse.jetty.util.ReadLineInputStream.readLine(ReadLineInputStream.java:68)
    at org.eclipse.jetty.util.MultiPartInputStreamParser.parse(MultiPartInputStreamParser.java:619)
    at org.eclipse.jetty.util.MultiPartInputStreamParser.getParts(MultiPartInputStreamParser.java:491)
    at org.eclipse.jetty.server.Request.getParts(Request.java:2374)
    at org.eclipse.jetty.server.Request.getParts(Request.java:2326)
    at com.github.tomakehurst.wiremock.servlet.WireMockHttpServletRequestAdapter.safelyGetRequestParts(WireMockHttpServletRequestAdapter.java:295)
    at com.github.tomakehurst.wiremock.servlet.WireMockHttpServletRequestAdapter.getParts(WireMockHttpServletRequestAdapter.java:279)
    at com.github.tomakehurst.wiremock.verification.LoggedRequest.createFrom(LoggedRequest.java:70)
    at com.github.tomakehurst.wiremock.stubbing.InMemoryStubMappings.serveFor(InMemoryStubMappings.java:76)
    at com.github.tomakehurst.wiremock.core.WireMockApp.serveStubFor(WireMockApp.java:164)
    at com.github.tomakehurst.wiremock.http.StubRequestHandler.handleRequest(StubRequestHandler.java:50)
    at com.github.tomakehurst.wiremock.http.AbstractRequestHandler.handle(AbstractRequestHandler.java:44)
    at com.github.tomakehurst.wiremock.servlet.WireMockHandlerDispatchingServlet.service(WireMockHandlerDispatchingServlet.java:108)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:841)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:543)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:481)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
    at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:666)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.Server.handle(Server.java:531)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:352)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
    at java.lang.Thread.run(Thread.java:750)
根因说明

异常和业务测试代码逻辑无关,是WireMock和Jetty的适配问题:WireMock记录请求时会自动调用Jetty内置的MultiPartInputStreamParser,尝试解析所有Content-Type带multipart标识的请求。SOAP MTOM传输二进制附件的分块格式和Jetty默认支持的multipart/form-data规范不兼容,二进制分块缺失标准行终止符,直接触发Jetty读行逻辑的缓冲区超限报错。

解决方案
  • 优先升级WireMock到2.27.0及以上版本,高版本已针对非标准multipart请求做容错处理。初始化WireMock规则时增加配置关闭请求自动解析,即可完全绕开报错:
WireMockRule wireMockRule = new WireMockRule(wireMockConfig()
        .port(8080)
        .disableRequestAudit()
);
  • 若暂时无法升级WireMock版本,直接调整桩配置:一是不要使用任何会触发multipart解析的匹配规则,仅保留URL和SOAP报文固定文本段的匹配逻辑;二是修正响应头配置,SOAP接口响应无需设置Content-Type: multipart/form-data,改为text/xml;charset=UTF-8,避免响应侧也触发不必要的解析逻辑。
  • 临时调试场景可直接在SOAP客户端关闭MTOM特性,将附件转base64编码后直接放在SOAP报文节点中传输,请求不再走multipart格式即可规避报错,调试完成后再恢复MTOM配置。

内容的提问来源于stack exchange,提问作者Lore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 17:54:26