Showing posts with label spring webservice. Show all posts
Showing posts with label spring webservice. Show all posts

Wednesday, October 9, 2013

Spring Webservice using WebServiceTemplate


WebServiceTemplate

Here is the bean
 <bean id="wsTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
                <property name="defaultUri" value="http://localhost:8080/quote_test"/>
                <property name="marshaller" ref="QuoteRequestJAXBMarshaller"/>                 
                <property name="unmarshaller" ref="QuoteResponseJAXBMarshaller"/>
        </bean> 

You will need Marshaller and Unmarshaller , its part of oxm
include these in the header
  xmlns:oxm = "http://www.springframework.org/schema/oxm"

setup the marshaller and unmarshaller

  
<oxm:jaxb2-marshaller id = "QuoteRequestJAXBMarshaller">
    <oxm:class-to-be-bound name = "com.quote.services.model.Quote"/>
  </oxm:jaxb2-marshaller>  
  
  <oxm:jaxb2-marshaller id = "QuoteResponseJAXBMarshaller">
    <oxm:class-to-be-bound name = "com.quote.services.model.QuoteResponse"/>
  </oxm:jaxb2-marshaller>  
Marshaller and a UnMarshaller can be generated by xjc utility on schema (or) wsimport on WSDL. If you don't have the schema , it can be generated by the xml using many tools like http://www.freeformatter.com/  Here is example of xjc using ant
 
  <?xml version = "1.0" encoding = "UTF-8"?>

<project name = "mywsproject" 
        default = "generate">
 <property file = "build.properties"/>
 
  <fileset id = "tools" 
           dir = "tools">
    <include name = "**/*.jar"/>
  </fileset> 
 
 <taskdef name = "xjc" classname = "com.sun.tools.xjc.XJCTask">
   <classpath>
     <fileset refid = "tools"/>
   </classpath>
 </taskdef>
 
 <target name = "generate">
  <xjc schema = "src/main/xml/quote.xsd" 
      destdir = "src/main/java" 
      package = "com.quote.services.model"/>
 </target> 
</project>


 WSDL will have the schema and "wsimport" utility will generate the Classes for Marshaling and Un-Marshaling ( details of the wsimport utility can be found here http://ajaxrocks.blogspot.com/2013/08/jax-ws-call-ws-using-maven.html) ,after generation delete the  webservice and webservice port type classes .

No matter which way you use for generating the classes , you have to review and look for  JAXBElement. Basically if jaxb-api can't find the type of the element , it will generate as JAXBElement , so your response  instead of a "QuoteResponse" will be JAXBElement< QuoteResponse > . It can be fixed by commenting the create method in the ObjectFactory class

 
//   @XmlElementDecl(namespace = "http://www.test.com/WS/QuoteWS", name = "QuoteResponse")
//   public JAXBElement<QuoteResponse> createQuoteResponse(QuoteResponse value) {
//       return new JAXBElement<QuoteResponse>( , QuoteResponse.class, null, value);
//   
}

This also can happen with the attributes . Example below "errorMessage" is string but not defined correctly in the schema  so it become a JAXBElement . Comment these out and create them as String , generate getters and Setters
 

//   @XmlElementRef(name = "errorMessage", type = JAXBElement.class)
//    protected JAXBElement<String> errorMessage;

Calling from Java Service , is now easy as calling a method and getting a response
@Service("myQuoteService")
public class QuoteServiceImpl {
    @Autowired
    private WebServiceOperations wsTemplate;
    
    
    public QuoteResponse generateQuote()
    {
     Quote quote = new Quote();
     quote.setPrice("99.99");
     quote.setAmount("100");
     
     QuoteRequest quoterequest = new QuoteRequest();
     quoterequest.setQuote(quote);
     
     return  (QuoteResponse)wsTemplate.marshalSendAndReceive(quoterequest);
     
    }
}