I'm new in SOAP technology,
I would like simply to test this endpoint :
My java file :
#Endpoint
public class DestinataireEndpoints {
private static final String NAMESPACE_URI = "http://www.opensolution.com/";
#Autowired
private DestinataireService destinataireService;
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "LiaisonResponse")
#ResponsePayload
public String LiaisonResponse() {
return "SAMPLE";
}
My xsd file:
<xs:element name="LiaisonResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="LiaisonResult" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
This is my configuration file:
#EnableWs
#Configuration
public class SoapConfig extends WsConfigurerAdapter {
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
#Bean(name = "destinataire")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema statesSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("StatesPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://www.opensolution.com/");
wsdl11Definition.setSchema(statesSchema);
return wsdl11Definition;
}
#Bean
public XsdSchema statesSchema() {
return new SimpleXsdSchema(new ClassPathResource("destinataire.xsd"));
}
I use SoapUI for testing and this is what I get :
What is missing ?
OK I understand !
I've got two elements in my xsd :
<xs:element name="Liaison">
<xs:complexType />
</xs:element>
<xs:element name="LiaisonResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="LiaisonResult" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
I have changed my EndPoint :
#Endpoint
public class DestinataireEndpoints {
private static final String NAMESPACE_URI = "http://www.opensolution.com/";
#Autowired
private DestinataireService destinataireService;
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "Liaison")
#ResponsePayload
public LiaisonResponse Liaison() {
LiaisonResponse liaisonResponse = new LiaisonResponse();
liaisonResponse.setLiaisonResult("tests");
return liaisonResponse;
}
I receive a "Liaison" element and I return a LiaisonResponse element
and I set liaisonResult attribute with String value
Related
i have a big problem calling a webService. When i did the import of the classes of the wsdl, i give this #WebService as a interface:
public void consultarProgramaCronicos(
#WebParam(name = "consultarProgramaCronicos", targetNamespace = "") ConsultarProgramaCronicosVO consultarProgramaCronicos,
#WebParam(name = "sip", targetNamespace = "", mode = WebParam.Mode.OUT) Holder<String> sip,
#WebParam(name = "programaCronico", targetNamespace = "", mode = WebParam.Mode.OUT) Holder<List<ProgramaCronicoVO>> programaCronico,
#WebParam(name = "marcaCronicidad", targetNamespace = "", mode = WebParam.Mode.OUT) Holder<List<MarcaCronicidadVO>> marcaCronicidad)
throws ConsultarProgramaCronicosFault;
So in my class, when i call this method i need to call it like this:
final Holder<String> sipHolder = new Holder<String>();
final Holder<List<ProgramaCronicoVO>> listProgramaCronico = new Holder<List<ProgramaCronicoVO>>();
final Holder<List<MarcaCronicidadVO>> listMarcaCronicidad = new Holder<List<MarcaCronicidadVO>>();
cronicos.consultarProgramaCronicos(cpc, sipHolder, listProgramaCronico, listMarcaCronicidad);
I pass an cpc object with the parameters i want, and i pass 3 holders for the answer.
The problem is i receive an object in the list but the primitive parameters of the object is "null".
This is the xml i receive:
<soap:Body wsu:Id="id-1995630735" xmlns:wsu="">
<consultarProgramaCronicosResponse xmlns="">
<sip>1703595</sip>
<marcaCronicidad>
<tipoMarca>CCC</tipoMarca>
<resultado>624</resultado>
<estadosalud>5</estadosalud>
<gravedad>1</gravedad>
<nivel>1</nivel>
<descripcionNivel>Texto cualquiera.</descripcionNivel>
</marcaCronicidad>
</consultarProgramaCronicosResponse></soap:Body>
In the "sip" holder i have the corrrect value. But In the List holder i have a list with one element of MarcaCronicidadV0, but all the string of this element are null.
Now, i show you a part of the .wsdl:
<xsd:complexType name="consultarProgramaCronicosResponse">
<xsd:sequence>
<xsd:element minOccurs="0" name="sip" type="xs:string"/>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="programaCronico" type="tns:programaCronicoVO"/>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="marcaCronicidad" type="tns:marcaCronicidadVO"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="marcaCronicidadVO">
<xsd:sequence>
<xsd:element name="tipoMarca" type="xs:string"/>
<xsd:element minOccurs="0" name="resultado" type="xs:string"/>
<xsd:element minOccurs="0" name="estadosalud" type="xs:string"/>
<xsd:element minOccurs="0" name="gravedad" type="xs:string"/>
<xsd:element minOccurs="0" name="nivel" type="xs:string"/>
</xsd:sequence>
</xsd:complexType>
And this is the class MarcaCronicidadVO:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "marcaCronicidadVO", namespace = "", propOrder = { "tipoMarca",
"resultado", "estadosalud", "gravedad", "nivel" })
public class MarcaCronicidadVO {
#XmlElement(required = true)
protected String tipoMarca;
protected String resultado;
protected String estadosalud;
protected String gravedad;
protected String nivel;
//getters y setters here
And in the end the "main object":
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "consultarProgramaCronicosResponse", namespace = "", propOrder = { "sip", "programaCronico","marcaCronicidad" })
public class ConsultarProgramaCronicosResponse {
protected String sip;
protected List<ProgramaCronicoVO> programaCronico;
protected List<MarcaCronicidadVO> marcaCronicidad;
public String getSip() {
return sip;
}
public void setSip(String value) {
this.sip = value;
}
public List<MarcaCronicidadVO> getMarcaCronicidad() {
if (marcaCronicidad == null) {
marcaCronicidad = new ArrayList<MarcaCronicidadVO>();
}
return this.marcaCronicidad;
}
public List<ProgramaCronicoVO> getProgramaCronico() {
if (programaCronico == null) {
programaCronico = new ArrayList<ProgramaCronicoVO>();
}
return this.programaCronico;
}
Why i dont have any error, and i recieve 3 correct holder, but in the holder list i have an element with attributes String with null value??????
Sorry by my english. Thank you!
I'm not sure why, but my problem is solved adding this parameter in the package-info class:
"elementFormDefault = XmlNsForm.QUALIFIED"
At the beginning i had this:
#javax.xml.bind.annotation.XmlSchema(namespace = "http://myUrl....")
Now i put:
#javax.xml.bind.annotation.XmlSchema(namespace = "http://myUrl....", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
And with this runs ok!
I hope to be helpful.
One of the Java webservices that I consume within my c# application has a returned type "marketCalendar" defined like following in the wsdl. WSDL's Target name space is http://www.xyz.com
<?xml version="1.0"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.xyz.com/wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.xyz.com/api" name="cscreen" targetNamespace="http://www.xyz.com/wsdl">
<wsdl:types>
<xsd:schema targetNamespace="http://www.xyz.com/api" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="getMarketCalendar">
<xsd:complexType>
</xsd:complexType>
</xsd:element>
<xsd:element name="marketCalendar">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="country" minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="exchange" minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="calendarDay" minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="type" type="calendarDayType" use="required"/>
<xsd:attribute name="date" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="sessionID" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<!--Get information on calendars -->
<wsdl:message name="getMarketCalendarRsp">
<wsdl:part name="marketCalendar" element="marketCalendar"/>
</wsdl:message>
<wsdl:message name="getMarketCalendarReq">
<wsdl:part name="getMarketCalendar" element="getMarketCalendar"/>
</wsdl:message>
<wsdl:portType name="Cscreen_PortType">
<wsdl:operation name="getMarketCalendarRequest">
<wsdl:input message="tns:getMarketCalendarReq"/>
<wsdl:output message="tns:getMarketCalendarRsp"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Cscreen_Binding" type="tns:Cscreen_PortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getMarketCalendarRequest">
<soap:operation soapAction=""/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Cscreen_Service">
<wsdl:documentation>This WSDL file describes how to access the Cscreen OTC Equity Derivatives Price Discovery Platform through the SOAP API. This software was developed by Cinnober Financial Technology.</wsdl:documentation>
<wsdl:port name="Cscreen_Port" binding="tns:Cscreen_Binding">
<soap:address location="https://hostname/api/v16"/>
<!-- hostname can for example be stage.xyz.com and www.xyz.com -->
</wsdl:port>
</wsdl:service>
and corresponding C# proxy has following interpretation,
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.18408")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://www.xyz.com")]
public partial class marketCalendar {
private marketCalendarCountry[] countryField;
private string sessionIDField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("country", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public marketCalendarCountry[] country {
get {
return this.countryField;
}
set {
this.countryField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string sessionID {
get {
return this.sessionIDField;
}
set {
this.sessionIDField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.18408")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://www.xyz.com")]
public partial class marketCalendarCountry {
private marketCalendarCountryExchange[] exchangeField;
private string nameField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("exchange", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public marketCalendarCountryExchange[] exchange {
get {
return this.exchangeField;
}
set {
this.exchangeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.18408")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://www.xyz.com")]
public partial class marketCalendarCountryExchange {
private marketCalendarCountryExchangeCalendarDay[] calendarDayField;
private string nameField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("calendarDay", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public marketCalendarCountryExchangeCalendarDay[] calendarDay {
get {
return this.calendarDayField;
}
set {
this.calendarDayField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.18408")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://www.xyz.com")]
public partial class marketCalendarCountryExchangeCalendarDay {
private calendarDayType typeField;
private string dateField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public calendarDayType type {
get {
return this.typeField;
}
set {
this.typeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string date {
get {
return this.dateField;
}
set {
this.dateField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.18408")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.xyz.com")]
public enum calendarDayType {
/// <remarks/>
HOLIDAY,
/// <remarks/>
EXPIRATION,
}
Problem# my c# application invokes a method GetMarketCalendar on the java webservice and does see the XML response coming in but can't deserialize it back into a marketCalendar response. So I started digging by using XGen generated class.
I noticed that for types country, exchange, calendarDay - c#'s default deserializer is comparing the namespace coming in the soap response to an empty string i.e.
if (((object) Reader.LocalName == (object)id84_country && (object) Reader.NamespaceURI == (object)id2_Item)) {
where incoming is Reader.NamespaceURI = "http://www.xyz.com" and id2_Item = Reader.NameTable.Add(#""); i.e. empty. Since comparision fails, deserialization also fails. Is there any work around?
Is this a C# XMLSerializer bug or there is something wrong with the marketCalendar definition in wsdl?
Here is a WSDL containing abstract global element named paramName:
<wsdl:definitions name="AdapterSessionManagerService" targetNamespace="http://companyname.org/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://companyname.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xs:schema elementFormDefault="unqualified" targetNamespace="http://companyname.org/" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<import namespace="http://companyname.org/adapter1/" schemaLocation="http://localhost:8081/adapters/AdapterSessionManager?xsd=adapter1/ElementName.xsd"/>
<import namespace="http://companyname.org/adapter2/" schemaLocation="http://localhost:8081/adapters/AdapterSessionManager?xsd=adapter2/ElementName.xsd"/>
<xs:element name="initAdapterSession" type="tns:initAdapterSession"/>
<xs:element name="initAdapterSessionResponse" type="tns:initAdapterSessionResponse"/>
<xs:complexType name="initAdapterSession">
<xs:sequence>
<xs:element name="adapterId" type="xs:long"/>
<xs:element name="callbackURL" type="xs:anyURI"/>
<xs:element name="adapterInputData" type="tns:AdapterInputDataType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="initAdapterSessionResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:long"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AdapterInputDataType">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="atomicParam" type="tns:AtomicParamType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AtomicParamType">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" ref="tns:paramName"/>
<xs:element maxOccurs="1" minOccurs="1" name="paramValue" type="tns:AtomicParamValueType"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="AtomicParamValueType">
<xs:union memberTypes="xs:string xs:long xs:decimal xs:dateTime xs:boolean"/>
</xs:simpleType>
<xs:element abstract="true" name="paramName" type="xs:string"/>
</xs:schema>
</wsdl:types>
<wsdl:message name="initAdapterSessionResponse">
<wsdl:part element="tns:initAdapterSessionResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="initAdapterSession">
<wsdl:part element="tns:initAdapterSession" name="parameters"/>
</wsdl:message>
<wsdl:portType name="AdapterSessionManager">
<wsdl:operation name="initAdapterSession">
<wsdl:input message="tns:initAdapterSession" name="initAdapterSession"/>
<wsdl:output message="tns:initAdapterSessionResponse" name="initAdapterSessionResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="AdapterSessionManagerServiceSoapBinding" type="tns:AdapterSessionManager">
<soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="initAdapterSession">
<soap12:operation soapAction="" style="document"/>
<wsdl:input name="initAdapterSession">
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output name="initAdapterSessionResponse">
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="AdapterSessionManagerService">
<wsdl:port binding="tns:AdapterSessionManagerServiceSoapBinding" name="AdapterSessionManagerPort">
<soap12:address location="http://localhost:8081/adapters/AdapterSessionManager"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
This element is intended to be subsituted in SOAP messages with same named elements defined in another namespaces. Here is an example of such definition:
<schema targetNamespace="http://companyname.org/adapter1/" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:inptypns="http://companyname.org/" xmlns:tns="http://companyname.org/adapter1/">
<import namespace="http://companyname.org/"/>
<element name="paramName" substitutionGroup="inptypns:paramName" type="tns:AtomicParamNameType"/>
<simpleType name="AtomicParamNameType">
<restriction base="string">
<enumeration value="foo"/>
<enumeration value="bar"/>
</restriction>
</simpleType>
</schema>
Here is Java code implementing this web-service including code generated by wsimport:
#WebService(wsdlLocation = "WEB-INF/wsdl/AdapterSessionManager.wsdl")
#BindingType(SOAPBinding.SOAP12HTTP_BINDING)
public class AdapterSessionManager {
#WebMethod
public Long initAdapterSession(
#WebParam(name = "adapterId")
#XmlElement(required = true)
Long adapterId,
#WebParam(name = "callbackURL")
#XmlElement(required = true)
URL callbackURL,
#WebParam
#XmlElement(required = true)
AdapterInputDataType adapterInputData
) {...}
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "AdapterInputDataType", propOrder = {
"atomicParam"
})
public class AdapterInputDataType {
protected List<AtomicParamType> atomicParam;
public List<AtomicParamType> getAtomicParam() {
if (atomicParam == null) {
atomicParam = new ArrayList<AtomicParamType>();
}
return this.atomicParam;
}
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "AtomicParamType", propOrder = {
"paramName",
"paramValue"
})
public class AtomicParamType {
#XmlElementRef(name = "paramName", namespace = "http://companyname.org/", type = JAXBElement.class)
protected JAXBElement<?> paramName;
#XmlElement(required = true)
protected String paramValue;
public JAXBElement<?> getParamName() {
return paramName;
}
public void setParamName(JAXBElement<?> value) {
this.paramName = value;
}
public String getParamValue() {
return paramValue;
}
public void setParamValue(String value) {
this.paramValue = value;
}
}
#XmlRegistry
public class ObjectFactory {
private final static QName _ParamName_QNAME = new QName("http://companyname.org/", "paramName");
public ObjectFactory() {
}
public AtomicParamType createAtomicParamType() {
return new AtomicParamType();
}
public AdapterInputDataType createAdapterInputDataType() {
return new AdapterInputDataType();
}
#XmlElementDecl(namespace = "http://companyname.org/", name = "paramName")
public JAXBElement<String> createParamName(String value) {
return new JAXBElement<String>(_ParamName_QNAME, String.class, null, value);
}
}
#XmlType(name = "AtomicParamNameType", namespace = "http://companyname.org/adapter1/")
#XmlEnum
public enum AtomicParamNameType {
#XmlEnumValue("foo")
FOO("foo"),
#XmlEnumValue("bar")
BAR("bar");
private final String value;
AtomicParamNameType(String v) {
value = v;
}
public String value() {
return value;
}
public static AtomicParamNameType fromValue(String v) {
for (AtomicParamNameType c: AtomicParamNameType.values()) {
if (c.value.equals(v)) {
return c;
}
}
throw new IllegalArgumentException(v);
}
}
#XmlRegistry
public class ObjectFactory {
private final static QName _ParamName_QNAME = new QName("http://companyname.org/adapter1/", "paramName");
public ObjectFactory() {
}
#XmlElementDecl(namespace = "http://companyname.org/adapter1/", name = "paramName", substitutionHeadNamespace = "http://companyname.org/", substitutionHeadName = "paramName")
public JAXBElement<AtomicParamNameType> createParamName(AtomicParamNameType value) {
return new JAXBElement<AtomicParamNameType>(_ParamName_QNAME, AtomicParamNameType.class, null, value);
}
}
I'm testing service with the following SOAP-request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://companyname.org/" xmlns:ans="http://companyname.org/adapter1/">
<soapenv:Header/>
<soapenv:Body>
<ws:initAdapterSession>
<adapterId>123</adapterId>
<callbackURL>http://callback</callbackURL>
<adapterInputData>
<atomicParam>
<ans:paramName>foo</ans:paramName>
<paramValue>hello</paramValue>
</atomicParam>
</adapterInputData>
</ws:initAdapterSession>
</soapenv:Body>
</soapenv:Envelope>
I have the following UnmarshallException when an application server receives the request:
javax.xml.bind.UnmarshalException: unexpected element
(uri:"http://companyname.org/adapter1/", local:"paramName"). Expected
elements are <{http://companyname.org/}paramName>,<{}paramValue>
Looks like JAXB is unaware of paramName substitution defined in http://companyname.org/adapter1/ namespace. But I can't imagine why JAXB behaves in such a way. Where is my mistake? Any ideas?
You already know the answer: http://companyname.org/adapter1 is not the same as http://companyname.org/.
Your generated source explicitly indicates that the paramName element is defined in the http://companyname.org/ namespace with the following line.
#XmlElementRef(name = "paramName", namespace = "http://companyname.org/", type = JAXBElement.class)
protected JAXBElement<?> paramName;
So change the namespace attribute to http://companyname.org/adapter1 to allow JAXB properly unmarshal your payload
I'm new to Spring-WS and I have defined an endpoint based off a schema generated from JAXB annotated classes. However, when I try to access the endpoint via soapUI, I get the following error along with a 404 response code:
No endpoint mapping found for [SaajSoapMessage {clip}clipClaimRequest]
Any ideas as to what I'm doing wrong? Thanks for any help given.
The endpoint class:
#Endpoint
public class TestEndpoint {
#PayloadRoot(localPart = "clipClaimRequest", namespace = "clip")
#ResponsePayload
public CLIPClaimResponse registerClaim(#RequestPayload CLIPClaimRequest request) {
return new CLIPClaimResponse("Success", "test success");
}
}
The request/response classes (marshalled/unmarshalled via JAXB):
#XmlRootElement(name = "clipClaimRequest")
#XmlType(name = "CLIPClaimRequest")
public class CLIPClaimRequest {
private Claim claim;
#XmlElement(required = true)
public Claim getClaim() {
return claim;
}
public void setClaim(Claim claim) {
this.claim = claim;
}
}
And:
#XmlRootElement(name = "clipClaimResponse")
#XmlType(name = "CLIPClaimResponse")
public class CLIPClaimResponse {
private String code;
private String description;
public CLIPClaimResponse() {
}
public CLIPClaimResponse(String code, String desc) {
setCode(code);
setDescription(desc);
}
#XmlElement(required = true)
public String getCode() {
return code;
}
#XmlElement(required = true)
public String getDescription() {
return description;
}
public void setCode(String code) {
this.code = code;
}
public void setDescription(String description) {
this.description = description;
}
}
web.xml servlet configuration:
<servlet>
<servlet-name>spring-ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<description>This is used by SpringWS to dynamically convert WSDL urls</description>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-ws</servlet-name>
<url-pattern>/clipClaimService/*</url-pattern>
</servlet-mapping>
spring-ws-servlet.xml configuration:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<context:annotation-config />
<sws:annotation-driven />
<sws:dynamic-wsdl id="claimRegistration" portTypeName="CLIPClaimPort"
locationUri="/clipClaimService/" targetNamespace="clip">
<sws:xsd location="/WEB-INF/CLIP_Poc.xsd" />
</sws:dynamic-wsdl>
<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<!-- list of classes... -->
</list>
</property>
<property name="schema" value="/WEB-INF/CLIP_PoC.xsd" />
</bean>
<bean id="marshallingPayloadMethodProcessor"
class="org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor">
<constructor-arg ref="jaxb2Marshaller" />
<constructor-arg ref="jaxb2Marshaller" />
</bean>
<bean id="defaultMethodEndpointAdapter"
class="org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter">
<property name="methodArgumentResolvers">
<list>
<ref bean="marshallingPayloadMethodProcessor" />
</list>
</property>
<property name="methodReturnValueHandlers">
<list>
<ref bean="marshallingPayloadMethodProcessor" />
</list>
</property>
</bean>
</beans>
And finally, CLIP_PoC.xsd, the schema from which the WSDL was generated:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="clip" targetNamespace="clip" version="1.0">
<xs:element name="clipClaimRequest" type="CLIPClaimRequest"/>
<xs:element name="clipClaimResponse" type="CLIPClaimResponse"/>
<!-- type definitions for all the complex elements used... -->
</xs:schema>
I figured it out. I had forgotten to put: <context:component-scan base-package="my.base.package"/> in my spring-ws-servlet.xml file. This fixed it somehow.
I have a SEI as
#WebService
#SOAPBinding
(
style = javax.jws.soap.SOAPBinding.Style.DOCUMENT,
use = javax.jws.soap.SOAPBinding.Use.LITERAL
)
#HandlerChain(file = "securityhandler.xml")
public interface UserService
{
#WebMethod
public AuthenticateResponse authenticateUser(AuthenticateRequest request,#WebParam(header = true, mode = Mode.IN) ApplicationCredentials credential);
}
I am using wsgen to generate server side class files and wsdl. What I noticed that wsgen generates wrapper on my request(AuthenticateRequest) as
package com.ecourt.ws.jaxws;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import com.ecourt.ws.impl.request.AuthenticateRequest;
#XmlRootElement(name = "authenticateUser", namespace = "http://ws.ecourt.com/")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "authenticateUser", namespace = "http://ws.ecourt.com/")
public class AuthenticateUser {
#XmlElement(name = "arg0", namespace = "")
private AuthenticateRequest arg0;
/**
*
* #return
* returns AuthenticateRequest
*/
public AuthenticateRequest getArg0() {
return this.arg0;
}
/**
*
* #param arg0
* the value for the arg0 property
*/
public void setArg0(AuthenticateRequest arg0) {
this.arg0 = arg0;
}
}
Now I am using a LogicalHandler to intercept SOAP Message and tried to unmarshall the payload to AuthenticateRequest, it throws exception:
javax.xml.ws.WebServiceException: javax.xml.bind.UnmarshalException: unexpected element (uri:"http://ws.ecourt.com/", local:"authenticateUser"). Expected elements are <{}authenticateRequest>,<{}baseRequest>
the handle message implementation of my handler is
#Override
public boolean handleMessage(LogicalMessageContext messageContext) {
try
{
System.out.println("in handle messgae of AuthenticationHandler");
Boolean outboundProperty = (Boolean)
messageContext.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if(outboundProperty == false)
{
JAXBContext jc = JAXBContext.newInstance(com.ecourt.ws.impl.request.AuthenticateRequest.class);
Object obj = messageContext.getMessage().getPayload(jc);
}
}
catch(Exception ex)
{
ex.printStackTrace();
return false;
}
return true;
}
This is the part of the xsd
<xs:element name="authenticateUser" type="tns:authenticateUser"/>
<xs:complexType name="authenticateUser">
<xs:sequence>
<xs:element name="arg0" type="tns:authenticateRequest" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
I just want to UnMarshall payLoad directly to AuthenticateRequest not AuthenticateUser generated by WSGen. Is there any way to do it? Any help would be highly appreciated
This is solved, I needed to use the other overloaded method in LogicalMessage Class that is:
Source source = messageContext.getMessage().getPayload();
And with the source we can handle the complete Soap Address.
Thanks