T
traveller
Hi,
I am doing examples from the great book "SOA Using Java Web Services"
by Mark D. Hansen. In several examples I need to use wsimport for
generating mapped classes from a WSDL file.
Issue No. 1
The thing is the classes are generated but there is a warning as
follows
--------------------- START ----------------------
[WARNING] src-resolve: Cannot resolve the name 'oms:BUSOBJ_CCARD' to
a(n) 'element declaration' component.
line 36 of file:/E:/.../Idea-SoaBook/chap07/ep-provider-castor/rsrc/
RequestOrder.wsdl#types?schema3
----------------------- END ------------------------
But still the classes are generated correctly and I can use them.
Issue no. 2
For the same WSDL file, in Chapter 7, in a program (in Section 7.3)
there is validation done using schemas extracted from the wsdl file
dynamically. The cause is the same, but this time the code fails and
the web service does not run at all and ultimately results in an
exception
Now I will list the relvant parts of the files which bear with this
problem
1) The WSDL file (Reproducing here)
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://www.example.com/req"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:req="http://www.example.com/req"
xmlnsms="http://www.example.com/oms"
xmlns:faults="http://www.example.com/faults">
<wsdl:types>
<xs:schema targetNamespace="http://www.example.com/oms">
<xs:include schemaLocation="http://soabook.com/example/oms/
orders.xsd"/>
</xs:schema>
<xs:schema targetNamespace="http://www.example.com/faults">
<xs:include schemaLocation="http://soabook.com/example/
faults/faults.xsd"/>
</xs:schema>
<xs:schema elementFormDefault="qualified"
targetNamespace="http://www.example.com/req">
<xs:import namespace="http://www.example.com/oms"/>
<xs:element name="requestOrder">
<xs:complexType>
<xs:sequence>
<xs:element name="CUST_NO">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="PURCH_ORD_NO" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="35"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="ccard"
type="oms:BUSOBJ_CCARD" minOccurs="0"/>
<xs:element name="item" type="oms:BUSOBJ_ITEM"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="requestOrderResponse">
<xs:complexType>
<xs:sequence>
<xs:element ref="oms:Order"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="request">
<wsdlart name="parameters" element="req:requestOrder"/>
</wsdl:message>
<wsdl:message name="response">
<wsdlart name="parameters"
element="req:requestOrderResponse"/>
</wsdl:message>
<!--! <example xn="WSDL_FAULT"> -->
<!--! <c>chap07</c><s>faults</s> -->
<wsdl:message name="inputFault">
<wsdlart name="parameters"
element="faults:inputMessageValidationFault"/>
</wsdl:message>
<wsdlortType name="RequestOrderPort">
<wsdlperation name="requestOrder">
<wsdl:input message="req:request"/>
<wsdlutput message="req:response"/>
<wsdl:fault name="requestOrderInputFault"
message="req:inputFault"/>
</wsdlperation>
</wsdlortType>
<!--! </example> -->
<wsdl:binding name="RequestOrderSOAPBinding"
type="req:RequestOrderPort">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/ <wsdlperation name="requestOrder">
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdlutput>
<soap:body use="literal"/>
</wsdlutput>
<wsdl:fault name="requestOrderInputFault">
<soap:fault name="requestOrderInputFault"/>
</wsdl:fault>
</wsdlperation>
</wsdl:binding>
<wsdl:service name="RequestOrderService">
<wsdlort name="RequestOrderPort"
binding="req:RequestOrderSOAPBinding">
<soap:address location="not yet determined"/>
</wsdlort>
</wsdl:service>
</wsdl:definitions>
2) Orders.xsd portion. The full file can be accessed at
http://soabook.com/example/oms/orders.xsd
<complexType name="BUSOBJ_CCARD">
<annotation>
<documentation>Credit Card Information</documentation>
</annotation>
<sequence>
<element name="CC_TYPE">
....
....
</complexType>
3) The Web Service code which tries to validate the incoming message
from the Client. This web service is decalred to be a provider, which
means that it will directly work with raw XML and not mapped Java
class objects. I am listing the relevant two methods which try to
carry out the validation
private String validateAgainstWSDL(Source payload) throws Exception {
//! <example xn="GET_WSDL_FROM_WEBCONTEXT">
//! <c>chap07</c><s>faults</s>
if ( webServiceContext == null ) {
throw new RuntimeException("WebServiceContext not injected.");
}
MessageContext mc = webServiceContext.getMessageContext();
ServletContext sc = (ServletContext)
mc.get(MessageContext.SERVLET_CONTEXT);
if ( sc == null ) {
throw new RuntimeException("ServletContext is null.");
}
InputStream wsdlStream =
sc.getResourceAsStream("/WEB-INF/wsdl/RequestOrder.wsdl");
//! </example>
if ( wsdlStream == null ) {
throw new IOException("WSDL resource not found.");
}
//! <example xn="EXTRACT_SCHEMA_FROM_WSDL_AND_VALIDATE">
//! <c>chap07</c><s>faults</s>
DocumentBuilderFactory dbfac =
DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document wsdlDoc = docBuilder.newDocument();
Transformer xformer =
TransformerFactory.newInstance().newTransformer();
xformer.transform(new StreamSource(wsdlStream), new
DOMResult(wsdlDoc));
NodeList schemaNodes = wsdlDoc.getElementsByTagNameNS(
XMLConstants.W3C_XML_SCHEMA_NS_URI, "schema");
int numOfSchemas = schemaNodes.getLength();
Source[] schemas = new Source[numOfSchemas];
Document schemaDoc;
Element schemaElt;
for (int i=0; i < numOfSchemas; i++) {
schemaDoc = docBuilder.newDocument();
NamedNodeMap nsDecls = getNamespaces((Element)
schemaNodes.item(i));
schemaElt = (Element) schemaDoc.importNode(schemaNodes.item(i),
true);
for (int j=0; j<nsDecls.getLength(); j++) {
Attr a = (Attr) schemaDoc.importNode(nsDecls.item(j), true);
schemaElt.setAttributeNodeNS(a);
}
schemaDoc.appendChild(schemaElt);
schemas = new DOMSource(schemaDoc);
}
SchemaFactory schemaFac = SchemaFactory.
newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFac.newSchema(schemas);
Validator validator = schema.newValidator();
if (!DOMSource.class.isInstance(payload) &&
!SAXSource.class.isInstance(payload) ) {
Document payloadDoc = docBuilder.newDocument();
xformer.transform(payload, new DOMResult(payloadDoc));
payload = new DOMSource(payloadDoc);
}
try {
validator.validate(payload);
} catch (SAXException se) {
//! </example>
se.printStackTrace();
return "validation error: " + se.getMessage();
} catch (IOException e) {
e.printStackTrace();
return "validation error: " + e.getMessage();
}
return null;
}
private NamedNodeMap getNamespaces(Element e) {
Element n = (Element) e.cloneNode(true);
NamedNodeMap attrs = n.getAttributes();
for (int i=0; i< attrs.getLength(); i++) {
Attr attr = (Attr) attrs.item(i);
String prefix = attr.getPrefix();
String name = attr.getLocalName();
if ( prefix == null || !prefix.equals("xmlns")) {
attrs.removeNamedItem(name);
}
}
Node parent = e.getParentNode();
if ( parent != null && parent.getNodeType() == Node.ELEMENT_NODE )
{
NamedNodeMap parentAttrs = getNamespaces((Element) parent);
for (int i=0; i<attrs.getLength(); i++) {
parentAttrs.setNamedItem(attrs.item(i).cloneNode(true));
}
return parentAttrs;
}
return attrs;
}
As you can see the WSDL is importing the namespace, has included the
Orders.xsd where duly oms:BUSOBJ_CCARD complexType is declared. And
still we have errors.
The full source code for the above mentioned book can be downloaded
from http://soabook.com.
If anyone is knowledgeable, please put some light on this issue. I
would be very grateful. It gnawing at my grey matter.
Cheers
Ravi
I am doing examples from the great book "SOA Using Java Web Services"
by Mark D. Hansen. In several examples I need to use wsimport for
generating mapped classes from a WSDL file.
Issue No. 1
The thing is the classes are generated but there is a warning as
follows
--------------------- START ----------------------
[WARNING] src-resolve: Cannot resolve the name 'oms:BUSOBJ_CCARD' to
a(n) 'element declaration' component.
line 36 of file:/E:/.../Idea-SoaBook/chap07/ep-provider-castor/rsrc/
RequestOrder.wsdl#types?schema3
----------------------- END ------------------------
But still the classes are generated correctly and I can use them.
Issue no. 2
For the same WSDL file, in Chapter 7, in a program (in Section 7.3)
there is validation done using schemas extracted from the wsdl file
dynamically. The cause is the same, but this time the code fails and
the web service does not run at all and ultimately results in an
exception
Now I will list the relvant parts of the files which bear with this
problem
1) The WSDL file (Reproducing here)
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://www.example.com/req"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:req="http://www.example.com/req"
xmlnsms="http://www.example.com/oms"
xmlns:faults="http://www.example.com/faults">
<wsdl:types>
<xs:schema targetNamespace="http://www.example.com/oms">
<xs:include schemaLocation="http://soabook.com/example/oms/
orders.xsd"/>
</xs:schema>
<xs:schema targetNamespace="http://www.example.com/faults">
<xs:include schemaLocation="http://soabook.com/example/
faults/faults.xsd"/>
</xs:schema>
<xs:schema elementFormDefault="qualified"
targetNamespace="http://www.example.com/req">
<xs:import namespace="http://www.example.com/oms"/>
<xs:element name="requestOrder">
<xs:complexType>
<xs:sequence>
<xs:element name="CUST_NO">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="PURCH_ORD_NO" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="35"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="ccard"
type="oms:BUSOBJ_CCARD" minOccurs="0"/>
<xs:element name="item" type="oms:BUSOBJ_ITEM"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="requestOrderResponse">
<xs:complexType>
<xs:sequence>
<xs:element ref="oms:Order"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="request">
<wsdlart name="parameters" element="req:requestOrder"/>
</wsdl:message>
<wsdl:message name="response">
<wsdlart name="parameters"
element="req:requestOrderResponse"/>
</wsdl:message>
<!--! <example xn="WSDL_FAULT"> -->
<!--! <c>chap07</c><s>faults</s> -->
<wsdl:message name="inputFault">
<wsdlart name="parameters"
element="faults:inputMessageValidationFault"/>
</wsdl:message>
<wsdlortType name="RequestOrderPort">
<wsdlperation name="requestOrder">
<wsdl:input message="req:request"/>
<wsdlutput message="req:response"/>
<wsdl:fault name="requestOrderInputFault"
message="req:inputFault"/>
</wsdlperation>
</wsdlortType>
<!--! </example> -->
<wsdl:binding name="RequestOrderSOAPBinding"
type="req:RequestOrderPort">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/ <wsdlperation name="requestOrder">
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdlutput>
<soap:body use="literal"/>
</wsdlutput>
<wsdl:fault name="requestOrderInputFault">
<soap:fault name="requestOrderInputFault"/>
</wsdl:fault>
</wsdlperation>
</wsdl:binding>
<wsdl:service name="RequestOrderService">
<wsdlort name="RequestOrderPort"
binding="req:RequestOrderSOAPBinding">
<soap:address location="not yet determined"/>
</wsdlort>
</wsdl:service>
</wsdl:definitions>
2) Orders.xsd portion. The full file can be accessed at
http://soabook.com/example/oms/orders.xsd
<complexType name="BUSOBJ_CCARD">
<annotation>
<documentation>Credit Card Information</documentation>
</annotation>
<sequence>
<element name="CC_TYPE">
....
....
</complexType>
3) The Web Service code which tries to validate the incoming message
from the Client. This web service is decalred to be a provider, which
means that it will directly work with raw XML and not mapped Java
class objects. I am listing the relevant two methods which try to
carry out the validation
private String validateAgainstWSDL(Source payload) throws Exception {
//! <example xn="GET_WSDL_FROM_WEBCONTEXT">
//! <c>chap07</c><s>faults</s>
if ( webServiceContext == null ) {
throw new RuntimeException("WebServiceContext not injected.");
}
MessageContext mc = webServiceContext.getMessageContext();
ServletContext sc = (ServletContext)
mc.get(MessageContext.SERVLET_CONTEXT);
if ( sc == null ) {
throw new RuntimeException("ServletContext is null.");
}
InputStream wsdlStream =
sc.getResourceAsStream("/WEB-INF/wsdl/RequestOrder.wsdl");
//! </example>
if ( wsdlStream == null ) {
throw new IOException("WSDL resource not found.");
}
//! <example xn="EXTRACT_SCHEMA_FROM_WSDL_AND_VALIDATE">
//! <c>chap07</c><s>faults</s>
DocumentBuilderFactory dbfac =
DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document wsdlDoc = docBuilder.newDocument();
Transformer xformer =
TransformerFactory.newInstance().newTransformer();
xformer.transform(new StreamSource(wsdlStream), new
DOMResult(wsdlDoc));
NodeList schemaNodes = wsdlDoc.getElementsByTagNameNS(
XMLConstants.W3C_XML_SCHEMA_NS_URI, "schema");
int numOfSchemas = schemaNodes.getLength();
Source[] schemas = new Source[numOfSchemas];
Document schemaDoc;
Element schemaElt;
for (int i=0; i < numOfSchemas; i++) {
schemaDoc = docBuilder.newDocument();
NamedNodeMap nsDecls = getNamespaces((Element)
schemaNodes.item(i));
schemaElt = (Element) schemaDoc.importNode(schemaNodes.item(i),
true);
for (int j=0; j<nsDecls.getLength(); j++) {
Attr a = (Attr) schemaDoc.importNode(nsDecls.item(j), true);
schemaElt.setAttributeNodeNS(a);
}
schemaDoc.appendChild(schemaElt);
schemas = new DOMSource(schemaDoc);
}
SchemaFactory schemaFac = SchemaFactory.
newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFac.newSchema(schemas);
Validator validator = schema.newValidator();
if (!DOMSource.class.isInstance(payload) &&
!SAXSource.class.isInstance(payload) ) {
Document payloadDoc = docBuilder.newDocument();
xformer.transform(payload, new DOMResult(payloadDoc));
payload = new DOMSource(payloadDoc);
}
try {
validator.validate(payload);
} catch (SAXException se) {
//! </example>
se.printStackTrace();
return "validation error: " + se.getMessage();
} catch (IOException e) {
e.printStackTrace();
return "validation error: " + e.getMessage();
}
return null;
}
private NamedNodeMap getNamespaces(Element e) {
Element n = (Element) e.cloneNode(true);
NamedNodeMap attrs = n.getAttributes();
for (int i=0; i< attrs.getLength(); i++) {
Attr attr = (Attr) attrs.item(i);
String prefix = attr.getPrefix();
String name = attr.getLocalName();
if ( prefix == null || !prefix.equals("xmlns")) {
attrs.removeNamedItem(name);
}
}
Node parent = e.getParentNode();
if ( parent != null && parent.getNodeType() == Node.ELEMENT_NODE )
{
NamedNodeMap parentAttrs = getNamespaces((Element) parent);
for (int i=0; i<attrs.getLength(); i++) {
parentAttrs.setNamedItem(attrs.item(i).cloneNode(true));
}
return parentAttrs;
}
return attrs;
}
As you can see the WSDL is importing the namespace, has included the
Orders.xsd where duly oms:BUSOBJ_CCARD complexType is declared. And
still we have errors.
The full source code for the above mentioned book can be downloaded
from http://soabook.com.
If anyone is knowledgeable, please put some light on this issue. I
would be very grateful. It gnawing at my grey matter.
Cheers
Ravi