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

Spring Boot+Apache Camel SOAP转REST遇Prolog内容错误求助

解决Apache Camel SOAP转REST时的SAXParseException(Content is not allowed in prolog)

你遇到的Content is not allowed in prolog错误,核心原因是从CXF端点获取的请求体并非原始XML字符串。CXF默认会将SOAP请求解析为SOAPMessage或Document对象,此时强行用getBody(String.class)转换得到的内容格式不符合XML解析要求,导致二次解析时出错。

以下是具体解决方案:

1. 正确获取CXF端点的原始SOAP请求内容

修改路由中的处理逻辑,通过CXF的Exchange属性获取原始XML,而不是直接转换body:

from("cxf:bean:soapCxfEndpoint")
    .log("Received SOAP request: ${body}")
    .process(exchange -> {
        // 从CXF消息中提取原始XML字符串
        org.apache.cxf.message.Message cxfMsg = exchange.getIn().getHeader(CxfConstants.CXF_MESSAGE, org.apache.cxf.message.Message.class);
        String soapRequest = cxfMsg.getContent(String.class).trim();
        
        String restRequest = transformSoapToRest(soapRequest);
        log.info("Transformed REST request: " + restRequest); // 修正原日志打印错误
        exchange.getIn().setBody(restRequest.trim());
    })
    // 后续路由逻辑保持不变
    .log("Transformed to REST request: ${body}")
    .to("http://localhost:8080/rest/api")
    // ... 其余代码

2. 避免重复解析XML(优化转换逻辑)

既然CXF已经完成SOAP消息解析,直接利用CXF提供的API提取arg0的值,无需自行二次解析:

private String transformSoapToRest(SOAPMessage soapMessage) throws SOAPException {
    SOAPBody soapBody = soapMessage.getSOAPBody();
    Node arg0Node = soapBody.getElementsByTagName("arg0").item(0);
    String requestData = arg0Node.getTextContent();
    return "{ \"requestData\": \"" + requestData + "\" }";
}

对应的路由修改:

from("cxf:bean:soapCxfEndpoint")
    .log("Received SOAP request: ${body}")
    .process(exchange -> {
        SOAPMessage soapMessage = exchange.getIn().getBody(SOAPMessage.class);
        String restRequest = transformSoapToRest(soapMessage);
        log.info("Transformed REST request: " + restRequest);
        exchange.getIn().setBody(restRequest.trim());
    })
    // 后续路由逻辑保持不变

3. 排查字符编码与BOM问题

如果上述方法仍无效,检查请求是否携带UTF-8 BOM(字节码为0xEFBBBF),可在转换前去除:

private String transformSoapToRest(String soapRequest) throws ParserConfigurationException, IOException, SAXException {
    soapRequest = soapRequest.trim();
    
    // 检查并去除UTF-8 BOM
    byte[] soapBytes = soapRequest.getBytes(StandardCharsets.UTF_8);
    if (soapBytes.length >=3 && soapBytes[0] == (byte)0xEF && soapBytes[1] == (byte)0xBB && soapBytes[2] == (byte)0xBF) {
        soapRequest = new String(soapBytes, 3, soapBytes.length-3, StandardCharsets.UTF_8);
    }
    
    // 原解析逻辑保持不变
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(new InputSource(new StringReader(soapRequest)));

    String requestData = document.getElementsByTagName("arg0").item(0).getTextContent();
    return "{ \"requestData\": \"" + requestData + "\" }";
}

额外修正:原代码中的日志错误

你在转换REST请求后的日志打印的是soapRequest,应改为restRequest,避免调试混淆:

// 原错误代码
log.info("Transformed rest request: " + soapRequest);
// 修正后
log.info("Transformed REST request: " + restRequest);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 18:54:54