Spring SOAP:如何移除SOAPExceptionResponse中<faultstring>的lang=en属性?
解决方案:移除SOAP Fault中faultstring的xml:lang属性
针对Spring SOAP框架自动添加xml:lang="en"到<faultstring>标签的问题,提供两种可行的落地方案:
方案一:自定义SoapFaultMappingExceptionResolver(推荐)
通过重写Spring默认的异常解析器,在创建Fault时直接跳过xml:lang属性的设置,从源头解决问题:
public class CustomSoapFaultResolver extends SoapFaultMappingExceptionResolver { @Override protected SoapFault createFault(SoapFaultDefinition definition, MessageContext messageContext) { SoapBody soapBody = getSoapBody(messageContext); // 仅传入faultCode和faultString,不指定Locale,避免生成xml:lang属性 SoapFault soapFault = soapBody.addFault(definition.getFaultCode(), definition.getFaultString()); if (definition.getFaultActor() != null) { soapFault.setFaultActor(definition.getFaultActor()); } return soapFault; } @Override protected void customizeFault(Object endpoint, Exception ex, SoapFault fault) { super.customizeFault(endpoint, ex, fault); // 额外兜底:如果仍有遗留的xml:lang属性,直接移除 Element faultStringElement = (Element) fault.getFaultStringElement(); if (faultStringElement != null && faultStringElement.hasAttribute("xml:lang")) { faultStringElement.removeAttribute("xml:lang"); } } }
在Spring配置中注册该自定义解析器,替换默认实现:
@Configuration public class SoapWebServiceConfig { @Bean public SoapFaultMappingExceptionResolver soapFaultMappingExceptionResolver() { CustomSoapFaultResolver resolver = new CustomSoapFaultResolver(); // 设置默认Fault规则(可根据业务需求调整) SoapFaultDefinition defaultFault = new SoapFaultDefinition(); defaultFault.setFaultCode(SoapFaultDefinition.SERVER); resolver.setDefaultFault(defaultFault); // 可选:添加自定义异常映射 // Properties faultMappings = new Properties(); // faultMappings.setProperty("com.yourpackage.MyException", "SOAP-ENV:Client"); // resolver.setFaultMappings(faultMappings); return resolver; } }
方案二:使用EndpointInterceptor全局拦截修改
通过拦截SOAP响应,在消息发送前手动移除xml:lang属性,适用于所有生成Fault的场景(包括手动构建的Fault):
public class FaultLangAttributeRemoverInterceptor implements EndpointInterceptor { @Override public boolean handleRequest(MessageContext messageContext, Object endpoint) { return true; } @Override public boolean handleResponse(MessageContext messageContext, Object endpoint) { modifyFaultStringLangAttribute(messageContext); return true; } @Override public boolean handleFault(MessageContext messageContext, Object endpoint) { modifyFaultStringLangAttribute(messageContext); return true; } @Override public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) {} private void modifyFaultStringLangAttribute(MessageContext messageContext) { SoapMessage soapMessage = (SoapMessage) messageContext.getResponse(); SoapBody soapBody = soapMessage.getSoapBody(); if (soapBody.hasFault()) { SoapFault soapFault = soapBody.getFault(); Element faultStringElement = (Element) soapFault.getFaultStringElement(); if (faultStringElement != null && faultStringElement.hasAttribute("xml:lang")) { faultStringElement.removeAttribute("xml:lang"); } } } }
将拦截器注册到Spring SOAP的端点配置链中:
@Configuration @EnableWs public class SoapWebServiceConfig extends WsConfigurerAdapter { @Override public void addInterceptors(List<EndpointInterceptor> interceptors) { interceptors.add(new FaultLangAttributeRemoverInterceptor()); super.addInterceptors(interceptors); } // 其他SOAP配置(如MessageDispatcherServlet、Wsdl11Definition等) }
方案选择建议
- 若仅需处理异常抛出的Fault,方案一更高效,直接从源头避免属性生成;
- 若需覆盖所有可能生成Fault的场景(比如手动构建的Fault),方案二更通用。
内容的提问来源于stack exchange,提问作者punkevich
相关产品推荐
相关产品推荐

