jax-ws document/literal wrapped unleashed (WS-I compliant)
Following rules should be applied strictly to develop a WS-I compliant document/literal wrapped web service.
- The input message must have a single part only.
- The part must be an element (beware it should not be a type).
- The element has the same name as the operation.
- The element has the same name as the operation.
Note: The first rule clearly says that WS-I compliant document/literal wrapped web service can not have explicit soap header. I’ll publish how to embed implicit header in my other post.
Let me present an example with its artifact of JAX-WS document/literal wrapped style web service.
The artifact are in following order:
1. WSDL
2. XSD
3. JAX-WS binding file
4. wsimport command used to generate jws file
5. Generated jws endpointInterface
6. jws implementation file
7. Sample SOAP request
8. Sample SOAP response
1. WSDL
<?xml version="1.0" encoding="UTF-8" ?> <definitions targetNamespace="http://www.bataahmaithil.in/techie/article/wsdoclitwrapped" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.bataahmaithil.in/techie/article/wsdoclitwrapped" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:header="http://www.bataahmaithil.in/techie/common/header"> <!--Part 1 of WSDL = types --> <types> <xsd:schema> <xsd:import namespace="http://www.bataahmaithil.in/techie/article/wsdoclitwrapped" schemaLocation="articlesearch.xsd" /> <xsd:import namespace="http://www.bataahmaithil.in/techie/common/header" schemaLocation="commonheader.xsd" /> </xsd:schema> </types> <!--Part 2 of WSDL = messages --> <message name="searchArticleRequest"> <part name="parameters" element="tns:searchArticle" /> </message> <message name="searchArticleResponse"> <part name="parameters" element="tns:searchArticleResp" /> </message> <!--Part 3 of WSDL = Port Type --> <portType name="ArticlePortType"> <operation name="searchArticle"> <input message="tns:searchArticleRequest" /> <output message="tns:searchArticleResponse" /> </operation> </portType> <!--Part 4 of WSDL = binding (port type and soap style) --> <binding name="ArticleBinding" type="tns:ArticlePortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="searchArticle"> <soap:operation soapAction="http://www.bataahmaithil.in/techie/article/wsdoclitwrapped/searchArticle" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding> <!--Part 5 of WSDL = service --> <service name="ArticleService"> <port binding="tns:ArticleBinding" name="ArticlePortType"> <soap12:address location="http://localhost:7001/ws_doc_lit_wrapped/ArticleService" /> </port> </service> </definitions> |
2. XSD
<?xml version="1.0" encoding="UTF-8" ?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.bataahmaithil.in/techie/article/wsdoclitwrapped" targetNamespace="http://www.bataahmaithil.in/techie/article/wsdoclitwrapped" elementFormDefault="qualified"> <!-- Elements --> <xsd:element name="searchArticle" type="ArticleSerach" /> <xsd:element name="searchArticleResp" type="ArticleSerachResult" /> <xsd:element name="article" type="Article" /> <!--Types --> <xsd:complexType name="ArticleSerach"> <xsd:sequence> <xsd:element type="xsd:string" name="category" maxOccurs="1" minOccurs="0" /> <xsd:element type="xsd:string" name="tag" maxOccurs="1" minOccurs="0" /> <xsd:element type="xsd:string" name="title" maxOccurs="1" minOccurs="1" /> <xsd:element type="xsd:string" name="content" maxOccurs="1" minOccurs="0" /> </xsd:sequence> </xsd:complexType> <xsd:complexType name="ArticleSerachResult"> <xsd:sequence> <xsd:element ref="article" minOccurs="0" maxOccurs="unbounded" /> </xsd:sequence> </xsd:complexType> <xsd:complexType name="Article"> <xsd:sequence> <xsd:element type="xsd:string" name="category" maxOccurs="unbounded" minOccurs="0" /> <xsd:element type="xsd:string" name="tag" maxOccurs="unbounded" minOccurs="0" /> <xsd:element type="xsd:string" name="title" maxOccurs="1" minOccurs="1" /> <xsd:element type="xsd:string" name="content" maxOccurs="1" minOccurs="1" /> </xsd:sequence> </xsd:complexType> </xsd:schema> |
3. JAX-WS binding file
<jaxws:bindings wsdlLocation="articlesearch.wsdl" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/jaxws http://java.sun.com/xml/ns/jaxws"> <jaxws:enableWrapperStyle>true</jaxws:enableWrapperStyle> </jaxws:bindings> |
4. wsimport command used to generate jws file
wsimport -keep -d ./src -b articlesearch-binding.xml articlesearch.wsdl
5. Generated jws endpointInterface
package in.bataahmaithil.techie.article.wsdoclitwrapped; import java.util.List; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper; /** * This class was generated by the JAX-WS RI. * JAX-WS RI 2.2.6hudson-86 * Generated source version: 2.2 * */ @WebService(name = "ArticlePortType", targetNamespace = "http://www.bataahmaithil.in/techie/article/wsdoclitwrapped") @XmlSeeAlso({ in.bataahmaithil.techie.article.wsdoclitwrapped.ObjectFactory.class, in.bataahmaithil.techie.common.header.ObjectFactory.class }) public interface ArticlePortType { /** * * @param content * @param title * @param category * @param tag * @return * returns java.util.List<in.bataahmaithil.techie.article.wsdoclitwrapped.Article> */ @WebMethod(action = "http://www.bataahmaithil.in/techie/article/wsdoclitwrapped/searchArticle") @WebResult(name = "article", targetNamespace = "http://www.bataahmaithil.in/techie/article/wsdoclitwrapped") @RequestWrapper(localName = "searchArticle", targetNamespace = "http://www.bataahmaithil.in/techie/article/wsdoclitwrapped", className = "in.bataahmaithil.techie.article.wsdoclitwrapped.ArticleSerach") @ResponseWrapper(localName = "searchArticleResp", targetNamespace = "http://www.bataahmaithil.in/techie/article/wsdoclitwrapped", className = "in.bataahmaithil.techie.article.wsdoclitwrapped.ArticleSerachResult") public List<Article> searchArticle( @WebParam(name = "category", targetNamespace = "http://www.bataahmaithil.in/techie/article/wsdoclitwrapped") String category, @WebParam(name = "tag", targetNamespace = "http://www.bataahmaithil.in/techie/article/wsdoclitwrapped") String tag, @WebParam(name = "title", targetNamespace = "http://www.bataahmaithil.in/techie/article/wsdoclitwrapped") String title, @WebParam(name = "content", targetNamespace = "http://www.bataahmaithil.in/techie/article/wsdoclitwrapped") String content); } |
6. jws implementation file
package in.bataahmaithil.techie.article.wsdoclitwrapped; import java.util.List; import javax.jws.WebService; import javax.xml.ws.BindingType; /** * This class was generated by the JAX-WS RI. JAX-WS RI 2.2.6hudson-86 Generated * source version: 2.2 * */ @WebService(portName = "ArticlePortType", serviceName = "ArticleService", targetNamespace = "http://www.bataahmaithil.in/techie/article/wsdoclitwrapped", wsdlLocation = "/wsdls/articlesearch.wsdl", endpointInterface = "in.bataahmaithil.techie.article.wsdoclitwrapped.ArticlePortType") @BindingType("http://schemas.xmlsoap.org/wsdl/soap/http") public class ArticleService_ArticlePortTypeImpl implements ArticlePortType { public ArticleService_ArticlePortTypeImpl() { } /** * * @param content * @param title * @param category * @param tag * @return returns * java.util.List<in.bataahmaithil.techie.article.wsdoclitwrapped * .Article> */ public List<Article> searchArticle(String category, String tag, String title, String content) { // code that does actual search on backend List<Article> listOfArticle = ArticleModel.searchArticle(category, tag, title, content); return listOfArticle; } } |
7. Sample SOAP request
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Header /> <env:Body> <searchArticle xmlns="http://www.bataahmaithil.in/techie/article/wsdoclitwrapped"> <!--Optional:--> <category>jee</category> <!--Optional:--> <tag>jbpm</tag> <title>JBPM5</title> <!--Optional:--> <content>JBPM</content> </searchArticle> </env:Body> </env:Envelope> |
8. Sample SOAP response
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Body> <searchArticleResp xmlns="http://www.bataahmaithil.in/techie/article/wsdoclitwrapped"> <article> <category>jee</category> <category>bpm</category> <tag>jbpm5</tag> <tag>bpmn</tag> <title>JBPM5 setup on Oracle or MySql</title> <content>Change/configure following files post JBPM5 installation as per Oracle or MySql..</content> </article> <article> <category>jee</category> <category>bpm</category> <tag>jbpm5</tag> <tag>jboss</tag> <title>Solving JBoss 5 classloading issues in JBPM 5.1.0 in a web application</title> <content>Today I was stumbled on one of the issue while starting a JBPM Process involving human task. The error was</content> </article> </searchArticleResp> </S:Body> </S:Envelope> |
References:
Leave a Reply