简体   繁体   English

Spring 4 ws 合约第一个 webservice 意外元素

[英]Spring 4 ws contract first webservice unexpected element

I am trying to build a contract first web service using spring ws.我正在尝试使用 spring ws 构建一个合同优先的 Web 服务。 Attached are the code and soap ui test file.附件是代码和soap ui测试文件。 Whenever I am trying to access this web service I am getting error每当我尝试访问此 Web 服务时,我都会收到错误消息

unexpected element (uri:"http://www.aig.com/service/policyinquiry/1/soap", local:"PolicySearchByOwnerSSN")

Could you please let me know what is missing?你能告诉我缺少什么吗?

WSDL WSDL

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:accord="http://ACORD.org/Standards/Life/2" xmlns:tns="http://www.test.com/service/policyinquiry/1/soap" 
 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="policyinquiry" targetNamespace="http://www.test.com/service/policyinquiry/1/soap">
  <wsdl:types>
    <xsd:schema targetNamespace="http://www.test.com/service/policyinquiry/1/soap" elementFormDefault="qualified">
    <xsd:import namespace="http://ACORD.org/Standards/Life/2" schemaLocation="TXLife2.37.00.xsd"/>
      <xsd:element name="PolicySearchByOwnerSSN">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element ref="accord:TXLife"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="PolicySearchByOwnerSSNResponse">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element ref="accord:TXLifeResponse"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="GetPolicyDetails">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="accord:TXLife"/>
            </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="GetPolicyDetailsResponse">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="accord:TXLifeResponse"/>
            </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="PolicySearchByOwnerSSNRequest">
    <wsdl:part element="tns:PolicySearchByOwnerSSN" name="PolicySearchByOwnerSSN"/>
  </wsdl:message>
  <wsdl:message name="PolicySearchByOwnerSSNResponse">
    <wsdl:part element="tns:PolicySearchByOwnerSSNResponse" name="PolicySearchByOwnerSSNResponse"/>
  </wsdl:message>
  <wsdl:message name="GetPolicyDetailsRequest">
    <wsdl:part name="GetPolicyDetails" element="tns:GetPolicyDetails"></wsdl:part>
  </wsdl:message>
  <wsdl:message name="GetPolicyDetailsResponse">
    <wsdl:part name="GetPolicyDetailsResponse" element="tns:GetPolicyDetailsResponse"></wsdl:part>
  </wsdl:message>
  <wsdl:portType name="policyinquiry">
    <wsdl:operation name="PolicySearchByOwnerSSN">
      <wsdl:input message="tns:PolicySearchByOwnerSSNRequest"/>
      <wsdl:output message="tns:PolicySearchByOwnerSSNResponse"/>
    </wsdl:operation>
    <wsdl:operation name="GetPolicyDetails">
        <wsdl:input message="tns:GetPolicyDetailsRequest"></wsdl:input>
        <wsdl:output message="tns:GetPolicyDetailsResponse"></wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="policyinquirySOAP" type="tns:policyinquiry">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="PolicySearchByOwnerSSN">
      <soap:operation soapAction="http://www.test.com/service/policyinquiry/1/soap/PolicySearchByOwnerSSN"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="GetPolicyDetails">
      <soap:operation soapAction="http://www.test.com/service/policyinquiry/1/soap/GetPolicyDetails"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="policyinquiry">
    <wsdl:port binding="tns:policyinquirySOAP" name="PolicyInquiry">
      <soap:address location="http://www.test.com/service/policyinquiry/1/soap"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Java Endpoint Java 端点

@Endpoint
public class PolicyServiceSOAPEndpoint {

    public static final String NAMESPACE_URI =  "http://www.test.com/service/policyinquiry/1/soap"; //"http://ACORD.org/Standards/Life/2";

    @Autowired
    PolicySearchByOwnerSSNService policySearchByOwnerSSNService;

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "PolicySearchByOwnerSSN")
    @ResponsePayload
    public PolicySearchByOwnerSSNResponse policySearchByOwnerSSN(@RequestPayload PolicySearchByOwnerSSN policySearchByOwnerSSN){
        Party owner = parties.get(ownerpartyid);
        if(null == owner){
            //TODO: Throw exception
        }

        String ownerssn = owner.getGovtID();

        return policySearchByOwnerSSNService.getPoliciesByOwnerSSN(ownerssn);
    }


    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "GetPolicyDetails")
    @ResponsePayload
    public GetPolicyDetailsResponse getPolicyDetails(@RequestPayload GetPolicyDetails getPolicyDetails){

        return null;
    }
}

Spring Configuration Class弹簧配置类

@EnableWs
@Configuration
public class PolicyInquiryServiceConfig extends WsConfigurerAdapter {

    @Bean
    public ServletRegistrationBean messageDispatcherServlet(ApplicationContext appContext){
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(appContext);
        servlet.setTransformWsdlLocations(false);
        return new ServletRegistrationBean(servlet, "/policyservice/*");
    }

    @Bean
    public SaajSoapMessageFactory messageFactory() {
        SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
        // messageFactory.setSoapVersion(SoapVersion.SOAP_12);
        messageFactory.setSoapVersion(SoapVersion.SOAP_11);
        return messageFactory;
    }

    @Bean(name = "policyinquiry")
    public Wsdl11Definition defaultWsdl11Definition(XsdSchema schema){

        SimpleWsdl11Definition wsdl11Definition = new SimpleWsdl11Definition();
        wsdl11Definition.setWsdl(new ClassPathResource("policyinquiry.wsdl"));


        return wsdl11Definition;
    }

    @Bean
    public XsdSchema txlifeSchema(){
        //return new SimpleXsdSchema(new ClassPathResource("policyinquiry.wsdl"));
        return null;
    }

    @Bean
    public PayloadValidatingInterceptor payloadValidator(){
        PayloadValidatingInterceptor payloadValidatingInterceptor = new PayloadValidatingInterceptor();
        payloadValidatingInterceptor.setValidateRequest(false);
        payloadValidatingInterceptor.setValidateResponse(true);
        payloadValidatingInterceptor.setSchema(new ClassPathResource("TXLife2.37.00.xsd"));
        return payloadValidatingInterceptor;
    }

    @Autowired
    PayloadValidatingInterceptor payloadValidatingInterceptor;

    @Override
    public void addInterceptors(List<EndpointInterceptor> interceptors) {
        // register the CustomEndpointInterceptor
        interceptors.add(payloadValidatingInterceptor);
        interceptors.add(new PayloadLoggingInterceptor());
        interceptors.add(new SoapEnvelopeLoggingInterceptor());
    }
}

SOAP UI Test XML SOAP UI 测试 XML

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://www.test.com/service/policyinquiry/1/soap" xmlns:ns="http://ACORD.org/Standards/Life/2">
   <soapenv:Header/>
   <soapenv:Body>
      <soap:PolicySearchByOwnerSSN>
        <ns:TXLife>
            <ns:TransRefGUID>b08f35df-3490-4c40-91c9-13a6e702892a</ns:TransRefGUID>
            <ns:TransType tc="212">Values Inquiry</ns:TransType>
            <ns:TransSubType tc="1004921209">Withdrawal</ns:TransSubType>
            <ns:TransExeDate>2017-06-21-07:00</ns:TransExeDate>
            <ns:TransExeTime>14:26:03-04:00</ns:TransExeTime>
            <ns:OLifE>
                <ns:Holding id="AnnuityOrder1212130">
                </ns:Holding>
                <ns:Party id="Party_PrimaryOwner">
                    <ns:PartyTypeCode tc="1">Person</ns:PartyTypeCode>
                    <ns:GovtID>1234567</ns:GovtID>
                </ns:Party>
                <ns:Relation id="PrimaryOwner_Relation" OriginatingObjectID="AnnuityOrder1212130" RelatedObjectID="Party_PrimaryOwner">
                    <ns:OriginatingObjectType tc="4">Holding</ns:OriginatingObjectType>
                    <ns:RelatedObjectType tc="6">Party</ns:RelatedObjectType>
                    <ns:RelationRoleCode tc="8">Primary Owner</ns:RelationRoleCode>
                </ns:Relation>
            </ns:OLifE>
        </ns:TXLife>
     </soap:PolicySearchByOwnerSSN>
   </soapenv:Body>
</soapenv:Envelope>

Changing the namespace of WS and its data did the trick 更改WS的名称空间及其数据可以解决问题

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:accord="http://ACORD.org/Standards/Life/2" xmlns:tns="http://www.test.com/service/policyinquiry/1/soap" 
 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="policyinquiry" xmlns:types="http://www.test.com/service/policyinquiry/types" targetNamespace="http://www.test.com/service/policyinquiry/1/soap">
  <wsdl:types>
    <xsd:schema targetNamespace="http://www.test.com/service/policyinquiry/types" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" version="1.0">
    <xsd:import namespace="http://ACORD.org/Standards/Life/2" schemaLocation="TXLife2.37.00.xsd" />
      <xsd:element name="PolicySearchByOwnerSSN">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element ref="accord:TXLife"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="PolicySearchByOwnerSSNResponse">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element ref="accord:TXLifeResponse"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="GetPolicyDetails">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="accord:TXLife"/>
            </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="GetPolicyDetailsResponse">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="accord:TXLifeResponse"/>
            </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="PolicySearchByOwnerSSNRequest">
    <wsdl:part element="types:PolicySearchByOwnerSSN" name="PolicySearchByOwnerSSN"/>
  </wsdl:message>
  <wsdl:message name="PolicySearchByOwnerSSNResponse">
    <wsdl:part element="types:PolicySearchByOwnerSSNResponse" name="PolicySearchByOwnerSSNResponse"/>
  </wsdl:message>
  <wsdl:message name="GetPolicyDetailsRequest">
    <wsdl:part name="GetPolicyDetails" element="types:GetPolicyDetails"></wsdl:part>
  </wsdl:message>
  <wsdl:message name="GetPolicyDetailsResponse">
    <wsdl:part name="GetPolicyDetailsResponse" element="types:GetPolicyDetailsResponse"></wsdl:part>
  </wsdl:message>
  <wsdl:portType name="policyinquiry">
    <wsdl:operation name="PolicySearchByOwnerSSN">
      <wsdl:input message="tns:PolicySearchByOwnerSSNRequest"/>
      <wsdl:output message="tns:PolicySearchByOwnerSSNResponse"/>
    </wsdl:operation>
    <wsdl:operation name="GetPolicyDetails">
        <wsdl:input message="tns:GetPolicyDetailsRequest"></wsdl:input>
        <wsdl:output message="tns:GetPolicyDetailsResponse"></wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="policyinquirySOAP" type="tns:policyinquiry">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="PolicySearchByOwnerSSN">
      <soap:operation soapAction="http://www.test.com/service/policyinquiry/1/soap/PolicySearchByOwnerSSN"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="GetPolicyDetails">
      <soap:operation soapAction="http://www.test.com/service/policyinquiry/1/soap/GetPolicyDetails"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="policyinquiry">
    <wsdl:port binding="tns:policyinquirySOAP" name="PolicyInquiry">
      <soap:address location="http://www.test.com/service/policyinquiry/1/soap"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Response Payload expects JAXBElement should pass both NAMESPACE_URI & Object in the QName.响应负载要求 JAXBElement 应该在 QName 中同时传递 NAMESPACE_URI 和 Object。 I have used below code snippet to resolve the issue.我使用下面的代码片段来解决这个问题。

@PayloadRoot(namespace = NAMESPACE_URI, localPart = "ObjectName" ) @ResponsePayload public JAXBElement methodName(@RequestPayload JAXBElement parameters) { @PayloadRoot(namespace = NAMESPACE_URI, localPart = "ObjectName" ) @ResponsePayload public JAXBElement methodName(@RequestPayload JAXBElement 参数) {

    //Method logic goes here

    return createResponseJaxbElement(response, ResponseObject.class);

}

private JAXBElement createResponseJaxbElement(T object, Class clazz) {私有 JAXBElement createResponseJaxbElement(T 对象,类 clazz){

return new JAXBElement<>(new QName(NAMESPACE_URI, clazz.getSimpleName()), clazz, object);

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM