2010-11-08 43 views
5

Tôi đang cố gắng viết một dịch vụ web bằng cách sử dụng thư viện dịch vụ web mùa xuân. Tôi có thể cấu hình các thiết bị đầu cuối của mình thành công và nó hoạt động tốt, nhưng tôi đang đối mặt với một số vấn đề với ánh xạ ngoại lệ.Cách tạo thông báo lỗi xà phòng tùy chỉnh bằng dịch vụ web mùa xuân

Tôi có thể lập bản đồ ngoại lệ bằng @SoapFault và SoapFaultAnnotationExceptionResolver nhưng định nghĩa wsdl như sau

<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> 

Làm thế nào tôi có thể viết một ngoại lệ xử lý cho định nghĩa dịch vụ này?

Cảm ơn bạn

Trả lời

7

Sau một số tìm kiếm khác, tôi tìm thấy 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); 

CẬP NHẬT

Đây là một triển khai mẫu hoàn thành Tôi đang sử dụng,

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(); 
    } 
} 
+0

Bạn đang kéo 'mMarshaller' từ đâu? –

+0

@Mark, tôi đã cập nhật câu trả lời. Xin vui lòng cho tôi biết nếu bạn có bất cứ đề nghị. –

+0

Tôi đã hy vọng bạn quản lý để cá nó ra khỏi 'MessageEndpoint' một nơi nào đó, nhưng cuối cùng tôi phụ thuộc tiêm nó như bạn làm. –

2

Tôi đã sử dụng thành công SOAP mùa xuân-WS để tạo ra một dịch vụ web. Bây giờ tôi đang làm việc thực hiện lỗi trong dịch vụ SOAP này và tôi đã có thể làm điều đó với một lớp mà tôi tạo ra như sau,

public class ServiceSoapFaultMappingExceptionResolver extends SoapFaultMappingExceptionResolver 

và bên trong hàm ghi đè sau,

@Override 


protected void customizeFault(Object endpoint, Exception ex, SoapFault fault) { 

//code for adding fault details 

    SoapFaultDefinition soapFaultDefinition = new SoapFaultDefinition(); 
    String ENVELOPE_NAMESPACE_URI = "http://schemas.xmlsoap.org/soap/envelope/"; 

    //  soapFaultDefinition.setFaultStringOrReason("--" + ex); 

    //  soapFaultDefinition.setLocale(Locale.ENGLISH); 

    QName CLIENT_FAULT_NAME = new QName(ENVELOPE_NAMESPACE_URI,"5003", "e"); 
    soapFaultDefinition.setFaultCode(CLIENT_FAULT_NAME); 
    setDefaultFault(soapFaultDefinition); 
    Result result = fault.addFaultDetail().getResult(); 

     // marshal 
     try { 
      JAXBContext.newInstance(ExceptionListType.class).createMarshaller().marshal(exceptionList, result); 

} 

Hãy this answer cho giải pháp gốc.

+0

Trong khi điều này về lý thuyết có thể trả lời câu hỏi, [nó sẽ là thích hợp hơn] (http://meta.stackoverflow.com/q/8259) để bao gồm các phần thiết yếu của câu trả lời ở đây, và cung cấp liên kết để tham khảo. – chappjc

+0

ok.i sẽ làm việc cần thiết. –

+1

@Himanshu vui lòng xem câu trả lời cập nhật là ok. –

Các vấn đề liên quan