我正在开发一个 Spring Web Services 项目,我需要自定义 SOAP 错误响应。具体来说,我想确保 SOAP 响应中的错误元素使用自定义命名空间前缀 s,而不是默认的。
这是我当前的handleFault 实现:
@Override
public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
SOAPEnvelope envelope = soapResponse.getSaajMessage().getSOAPPart().getEnvelope();
SOAPBody body = envelope.getBody();
SOAPHeader header = soapResponse.getSaajMessage().getSOAPHeader();
// Remove the default "SOAP-ENV" namespace and replace it with "s"
envelope.removeNamespaceDeclaration("SOAP-ENV");
envelope.addNamespaceDeclaration("s", "http://schemas.xmlsoap.org/soap/envelope/");
// Set the prefix "s" for the envelope, body, and header
envelope.setPrefix("s");
body.setPrefix("s");
if (header != null) {
header.setPrefix("s");
}
// Create a new SOAPFault or modify the existing one
SOAPFault fault = body.getFault() != null ? body.getFault() : body.addFault();
fault.setPrefix("s");
fault.setFaultCode(new QName("http://schemas.xmlsoap.org/soap/envelope/", "Client", "s"));
fault.setFaultString("403 Forbidden: Access forbidden. Please check your permissions.");
// Save the changes to ensure everything is serialized properly
soapResponse.getSaajMessage().saveChanges();
return true;
}
此代码生成以下 SOAP 响应:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header/>
<s:Body>
<Fault xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode xmlns="">s:Client</faultcode>
<faultstring xml:lang="en" xmlns="">403 Forbidden: message[403 Forbidden from PUT http://127.0.0.1:8081/vms/display/screenwalls/scrwall_test_error403/mapping] responseBody[{"status":"ERROR","payload":"VMS Error Payload 403 (scrwall_test_error403) (scrwall_test_error403)"}]</faultstring>
</Fault>
</s:Body>
</s:Envelope>
如您所见,尽管调用了fault.setPrefix("s"),但Fault 元素缺少 s 前缀
而不是 ,我希望它像这样
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header/>
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring xml:lang="en">403 Forbidden: message[403 Forbidden]</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
如何确保 SOAP 正文中的Fault 元素使用 s 前缀?
我发现问题了。故障处理程序代码确实是正确的。这是 @Override public void afterCompletion(...) 方法用
覆盖前缀 node.setPrefix("");
我做了这个改变并且它正在起作用
// Check if the element is a Fault, and skip modifying the prefix
if (!"Fault".equals(node.getLocalName())) {
node.setPrefix("");