gpt4 book ai didi

spring-ws - 如何使用spring web服务创建自定义soap故障消息

转载 作者:行者123 更新时间:2023-12-04 17:40:53 26 4
gpt4 key购买 nike

我正在尝试使用 Spring Web 服务库编写一个 Web 服务。我能够成功配置我的端点并且工作正常,但是我遇到了一些异常映射问题。

我可以使用@SoapFault 和 SoapFaultAnnotationExceptionResolver 映射异常,但 wsdl 定义如下

<xsd:schema elementFormDefault="qualified" targetNamespace="http://abc.com/soap/">
<xsd:complexType name="ServiceException">
<xsd:sequence>
<xsd:element name="message" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>

<xsd:complexType name="ValidationException">
<xsd:complexContent>
<xsd:extension base="tns:ServiceException">
<xsd:sequence/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="InternalException">
<xsd:complexContent>
<xsd:extension base="tns:ServiceException">
<xsd:sequence/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="AuthenticationException">
<xsd:complexContent>
<xsd:extension base="tns:ServiceException">
<xsd:sequence/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="LoginInput">
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="1" name="UserName" nillable="false" type="xsd:string"/>
<xsd:element minOccurs="1" maxOccurs="1" name="PassWord" nillable="false" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>

<xsd:complexType name="LoginOutput">
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="1" name="ValidTo" nillable="false" type="xsd:dateTime"/>
</xsd:sequence>
</xsd:complexType>

<xsd:element name="login" type="tns:LoginInput"/>
<xsd:element name="loginResponse" type="tns:LoginOutput"/>

<xsd:element name="ValidationException" type="tns:ValidationException"/>
<xsd:element name="InternalException" type="tns:InternalException"/>
<xsd:element name="AuthenticationException" type="tns:AuthenticationException"/>
</xsd:schema>

<message name="LoginRequest">
<part name="login" element="tns:login"/>
</message>

<message name="LoginResponse">
<part name="loginResponse" element="tns:loginResponse"/>
</message>

<message name="ValidationException">
<part name="ValidationException" element="tns:ValidationException"/>
</message>

<message name="InternalException">
<part name="InternalException" element="tns:InternalException"/>
</message>

<message name="AuthenticationException">
<part name="AuthenticationException" element="tns:AuthenticationException"/>
</message>

<portType name="ServicePortType">
<operation name="Login">
<input message="tns:LoginRequest"/>
<output message="tns:LoginResponse"/>
<fault name="ValidationException" message="tns:ValidationException"/>
<fault name="InternalException" message="tns:InternalException"/>
<fault name="AuthenticationException" message="tns:AuthenticationException"/>
</operation>
</portType>

<binding name="ServiceBinding" type="tns:ServicePortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="Login">
<soap:operation soapAction="urn://Service#Login"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
<fault name="ValidationException">
<soap:fault name="ValidationException" use="literal"/>
</fault>
<fault name="InternalException">
<soap:fault name="InternalException" use="literal"/>
</fault>
<fault name="AuthenticationException">
<soap:fault name="AuthenticationException" use="literal"/>
</fault>
</operation>
</binding>

如何为该服务定义编写异常处理?

谢谢

最佳答案

经过更多的搜索,我找到了 this from spring source forum .

SoapMessage response = (SoapMessage) messageContext.getResponse();
SoapBody soapBody = response.getSoapBody();

SoapFault soapFault =
soapBody.addClientOrSenderFault(ex.getMessage(), Locale.ENGLISH);

SoapFaultDetail faultDetail = soapFault.addFaultDetail();
Result result = faultDetail.getResult();

// My detail XML object
InvalidArgumentFault fault = new InvalidArgumentFault();
fault.setErrorCode("Custom Error Code");
fault.setOpsMessage("This is the ops message");
fault.setSystemMessage("This is the system message");

// Marshal the detail. We have to use the ObjectFactory which isn't
// marshaller agnostic because the detail element doesn't have an
// XmlRootElement tag as required by JAXB.
ObjectFactory of = new ObjectFactory();
mMarshaller.marshal(of.createInvalidArgumentFault( fault), result);

更新

这是我正在使用的完整示例实现,
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.xml.transform.Result;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.oxm.Marshaller;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.endpoint.AbstractEndpointExceptionResolver;
import org.springframework.ws.soap.SoapBody;
import org.springframework.ws.soap.SoapFault;
import org.springframework.ws.soap.SoapFaultDetail;
import org.springframework.ws.soap.SoapMessage;

import org.apache.commons.lang.StringUtils;

public class CustomSoapFaultDetailAnnotationExceptionResolver extends
AbstractEndpointExceptionResolver implements ApplicationContextAware {
private static Log log = LogFactory
.getLog(CustomSoapFaultDetailAnnotationExceptionResolver.class);

private Collection<Marshaller> marshallers;

private Map<Class<? extends Object>, Marshaller> marshallerMap = new HashMap<Class<? extends Object>, Marshaller>();

public CustomSoapFaultDetailAnnotationExceptionResolver() {
setWarnLogCategory(getClass().getCanonicalName());
}

@Override
protected boolean resolveExceptionInternal(MessageContext messageContext,
Object endpoint, Exception ex) {
boolean resolved = false;

try {
CustomSoapFaultDetails annotation = ex.getClass().getAnnotation(
CustomSoapFaultDetails.class);
if (annotation != null) {

Method m = ex.getClass().getMethod("getFaultInfo",
new Class[] {});
Object fault = m.invoke(ex, new Object[] {});

SoapMessage response = (SoapMessage) messageContext
.getResponse();
SoapBody soapBody = response.getSoapBody();

SoapFault soapFault = soapBody
.addClientOrSenderFault(
StringUtils.isBlank(ex.getMessage()) ? "server exception"
: ex.getMessage(), Locale.ENGLISH);

SoapFaultDetail faultDetail = soapFault.addFaultDetail();
Result result = faultDetail.getResult();

if (marshallerMap.containsKey(fault.getClass())) {
marshallerMap.get(fault.getClass()).marshal(fault, result);
resolved = true;
} else {
for (Marshaller marshaller : marshallers) {
try {
marshaller.marshal(fault, result);
marshallerMap.put(fault.getClass(), marshaller);
resolved = true;
break;
} catch (Exception e) {
// Ignore error
}
}
}
}
} catch (Exception e) {
log.error(e.toString(), e);
}
return resolved;
}

@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.marshallers = applicationContext.getBeansOfType(Marshaller.class)
.values();
}
}

关于spring-ws - 如何使用spring web服务创建自定义soap故障消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4121318/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com