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

如何调整Grails CXF SOAP服务响应,将iniwebresult放入iniresponsewrapper?

Grails CXF SOAP服务响应结构调整问题

问题背景

我尝试用Groovy编写Grails CXF SOAP服务,现有代码如下:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement()
class Input {
    @XmlElement(name = "memberCode", required = true, namespace = "java:financial.sekuritas.pt.com.doReceivePushData")
    String memberCode
    @XmlElement(name = "fileContents", required = true, namespace = "java:financial.sekuritas.pt.com.doReceivePushData")
    String fileContents
    @XmlElement(name = "crc32", required = true, namespace = "java:financial.sekuritas.pt.com.doReceivePushData")
    String crc32
    @XmlElement(name = "urlWS", required = true, namespace = "java:financial.sekuritas.pt.com.doReceivePushData")
    String urlWS

}

@Transactional
@GrailsCxfEndpoint(address = "/doReceivePushData")
class ReportInvestorAccountCIMBService {    
    @Resource WebServiceContext context
    @WebMethod(operationName = "doReceivePushData")
    @WebResult(header = true, name = "iniwebresult")
    @ResponseWrapper(localName="iniresponsewrapper")
    public String doReceivePushData(@WebParam(name = 'input') 
    @XmlElement(name = "input", required = true, namespace = "http://financial.sekuritas.pt.com/") Input Input)

    { 
       return 1
    }
        
}

当前生成的SOAP响应结构:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <doReceivePushDataResponse>
      <iniresponsewrapper/>
      <iniwebresult>string</iniwebresult>
    </doReceivePushDataResponse>
  </soap:Body>
</soap:Envelope>

期望的SOAP响应结构:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <doReceivePushDataResponse>
          <iniresponsewrapper>
          <iniwebresult>string</iniwebresult>
         </iniresponsewrapper>
        </doReceivePushDataResponse>
      </soap:Body>
    </soap:Envelope>

需要修改代码让iniwebresult被包裹在iniresponsewrapper标签内。

解决方案

问题根源在于两个点:

  • @WebResult(header = true)会把结果放到SOAP头部而非响应体的包装器内,直接导致iniwebresult脱离了iniresponsewrapper。
  • 直接返回String类型无法和@ResponseWrapper正确配合,需要创建专门的响应包装类承载结果字段。

步骤1:创建响应包装类

新增带JAXB注解的包装类,将iniwebresult作为其字段:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "iniresponsewrapper")
class IniResponseWrapper {
    @XmlElement(name = "iniwebresult", required = true)
    String iniwebresult
}

步骤2:修改服务类方法

调整服务类的注解和返回类型,移除header = true,并返回包装类实例:

@Transactional
@GrailsCxfEndpoint(address = "/doReceivePushData")
class ReportInvestorAccountCIMBService {    
    @Resource WebServiceContext context

    @WebMethod(operationName = "doReceivePushData")
    @WebResult(name = "iniresponsewrapper")
    public IniResponseWrapper doReceivePushData(
        @WebParam(name = 'input') 
        @XmlElement(name = "input", required = true, namespace = "http://financial.sekuritas.pt.com/") Input input)
    { 
       def response = new IniResponseWrapper()
       response.iniwebresult = "1" // 返回字符串类型的"1",对应期望的string节点
       return response
    }
        
}

说明

  • 移除@ResponseWrapper注解,自定义的IniResponseWrapper类已直接定义响应结构,CXF会自动基于该类生成对应包装节点。
  • 返回类型从String改为IniResponseWrapper,确保结果被正确包裹在iniresponsewrapper内部。
  • 去掉@WebResult的header = true属性,让结果出现在SOAP体的包装器中。

修改后生成的SOAP响应会符合期望结构,iniwebresult将被包裹在iniresponsewrapper标签内。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 20:23:11