Apache Camel CXF调用SOAP报HolderInInterceptor索引越界异常修复
不需要替换HolderInInterceptor,这个异常是请求参数构造不符合CXF JAX-WS调用约定导致的。
先明确报错涉及的核心逻辑:HolderInInterceptor是CXF实现JAX-WS规范的内置拦截器,专门处理方法签名中javax.xml.ws.Holder类型的INOUT、OUT参数——这类参数用于在响应返回时承载非主体的返回值(比如响应头、分页信息、状态字段等)。CXF发起调用前会根据目标方法的签名长度初始化outHolders列表,响应返回后按参数索引把对应的值填充到列表的对应位置。
你遇到的Index 1 out of bounds for length 1,本质是传的请求参数数组长度,和getTransactionData方法的实际签名参数长度不匹配:
你注释里能正常跑的getCPNInstances、getOrgsAndStationGroups两个接口,方法签名只有1个请求对象入参,没有额外的Holder类型参数,所以传长度为1的Object数组是符合要求的。但getTransactionData的WSDL定义中,除了你传入的GetTransDataSearchRequest请求对象外,至少还有1个OUT/INOUT模式的参数(通常是SOAP响应头对应的Holder),方法总参数个数是2。你只传了长度1的参数数组,CXF初始化outHolders时只创建了长度为1的列表,处理响应时要往索引1的位置存第二个参数的返回值,直接触发越界。
- 核对生成的服务接口方法签名
找到WSDL编译生成的dictionary.com_chargepoint_webservices.Chargepointservices类,定位getTransactionData方法的完整定义,确认所有参数的顺序和类型,举个典型的生成后方法签名示例:GetTransDataSearchResponse getTransactionData( GetTransDataSearchRequest request, Holder<TransactionResponseHeader> outHeader ); - 修正请求体构造逻辑
在SoapRequestProcessor中按照方法签名的参数顺序,把所有参数位都补全,哪怕是OUT类型的Holder参数初始传空值也可以,CXF会在处理响应时自动填充内容。对应上面示例的修正代码:// 构造业务请求参数 GetTransDataSearchRequest request = new GetTransDataSearchRequest(); // 初始化方法签名要求的OUT类型Holder占位 Holder<TransactionResponseHeader> responseHeaderHolder = new Holder<>(); // 按方法签名顺序组装参数数组,数组长度必须和方法参数个数完全一致 exchange.getIn().setHeader(Header.HEADER_LIST, soapHeaders); exchange.getIn().setBody(new Object[]{request, responseHeaderHolder}); - 兜底排查项
如果补全参数后仍然报错,依次检查两点:- 确认运行时依赖的CXF版本,和编译WSDL生成stub代码用的CXF插件版本完全一致,避免版本差异导致的方法签名解析偏差
- 检查WSDL中是否有绑定到方法参数的SOAP Header定义,如果有,这类Header不能只通过
Header.HEADER_LIST传递,也要按参数顺序放入请求的Object数组中。
不要尝试移除或自定义替换
HolderInInterceptor,该拦截器是JAX-WS参数处理的核心组件,替换后会导致所有返回值、OUT参数解析逻辑完全错乱。
内容的提问来源于stack exchange,提问作者Pankaj Verma

