当前位置: 代码迷 >> Web前端 >> 【通译】Spring Web Services 2 - Part II ( Marshalling , UnMarshalling using JAXB)
  详细解决方案

【通译】Spring Web Services 2 - Part II ( Marshalling , UnMarshalling using JAXB)

热度:612   发布时间:2012-09-01 09:33:03.0
【翻译】Spring Web Services 2 - Part II ( Marshalling , UnMarshalling using JAXB)
原文地址: http://panbhatt.blogspot.com/2011/03/spring-web-services-2-part-i.html

In second part of the series, we will talk about how to use Marshaller's in order to automatically convert your request and response object to the SOAP Body XML (of request n response ) with the corresponding Namespace defined in the Java Source files.
Just like the first part, we will use Spring WS2- Part I we will use the same web service hosted at W3Schools.com but this time, with a very short code, as compared to Part-I .
Spring Web Services 2 makes use of a number of marshallers and unmarshallers in order to perform the tasks that include Spring OXM, Castom, Jaxb2. As JAXB 2 is the specification, so we will go by that only.

Note: Please add Jaxb libraries in your classpath while performing the action during this tutorial.

Configuration: So we will directly delve in the spring configuration (acjaxb.xml) as required for this tutorial.

<beans:beans xmlns:aop="http://www.springframework.org/schema/aop" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	       http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
	       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
	       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
	       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	 
	 
	     
	    <beans:bean class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" id="messageFactory">
	     
	    <beans:bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller" id="marshaller">
	        <beans:property name="classesToBeBound">
	        
	            <beans:list>
	 
	                <beans:value>springwsjxb.CelsiusToFahrenheit</beans:value>
	                <beans:value>springwsjxb.CelsiusToFahrenheitResponse</beans:value>
	                 
	            </beans:list>
	        </beans:property>
	   
	        <beans:property name="marshallerProperties">
	            <beans:map>
	                <beans:entry key="jaxb.formatted.output" value-ref="true">
	            </beans:entry></beans:map>
	        </beans:property>
	    </beans:bean>
	 
	    <beans:bean class="java.lang.Boolean" id="true">
	        <beans:constructor-arg value="True">
	    </beans:constructor-arg></beans:bean>
	 
	      
	     <beans:bean class="org.springframework.ws.client.core.WebServiceTemplate" id="webServiceTemplate">
	        <beans:constructor-arg ref="messageFactory">
	        <beans:property name="defaultUri" value="http://www.w3schools.com/webservices/tempconvert.asmx">
	         
	        <beans:property name="marshaller" ref="marshaller">
	        <beans:property name="unmarshaller" ref="marshaller">
	    </beans:property></beans:property></beans:property></beans:constructor-arg></beans:bean>
	 
	 
	</beans:bean></beans:beans>


As our current configuration describes that we are using two classes CelsiusToFahrenheit and CelsiusToFahrenheitResponse present in the springws packagejxb. Here is the corresponding source code for both of them. The Source code includes the Namespace details also, it becomes very important once we need to generate the XML, in any case if we missed out the namespace the coressponding web service will not be able to parse it and will throw an exception.

CelsiusToFahrenheit.java

package springwsjxb;
	 
	import javax.xml.bind.annotation.XmlElement;
	import javax.xml.bind.annotation.XmlRootElement;
	import javax.xml.bind.annotation.XmlType;
	 
	/**
	 *
	 * @author PankajB
	 */
	@XmlType(name="tem")
	@XmlRootElement(name="CelsiusToFahrenheit",namespace="http://tempuri.org/")
	public class CelsiusToFahrenheit {
	 
	    private int celsius;
	    
	 
	    @XmlElement(name="Celsius",namespace="http://tempuri.org/")
	    public int getCelsius() {
	        return celsius;
	    }
	 
	    public void setCelsius(int celsius) {
	        this.celsius = celsius;
	    }
	}
	<span class="Apple-style-span" style="font-family: 'Times New Roman';"><span class="Apple-style-span" style="white-space: normal;">
	</span></span>


CelsiusToFahrenheitResponse.java

package springwsjxb;
	 
	import javax.xml.bind.annotation.XmlElement;
	import javax.xml.bind.annotation.XmlRootElement;
	 
	 
	@XmlRootElement(name="CelsiusToFahrenheitResponse",namespace="http://tempuri.org/")
	public class CelsiusToFahrenheitResponse {
	 
	    private int result;
	 
	    //CelsiusToFahrenheitResult is the name of the XML Element which is being returned from the Web service and belongs to namespace "http://tempuri.org/"
	 
	    @XmlElement(name="CelsiusToFahrenheitResult",namespace="http://tempuri.org/")
	    public int getResult() {
	        return result;
	    }
	 
	    public void setResult(int result) {
	        this.result = result;
	    }
	 
	}


As per the requirements of the web service, we had kept only those variables here in our objects.
Now our Main.java file which will be responsible for invoking the web service and give us the response object.


Main.java

package springwsjxb;
	 
	import java.io.StringReader;
	import java.io.StringWriter;
	import javax.xml.bind.JAXBContext;
	import javax.xml.bind.Marshaller;
	import javax.xml.transform.stream.StreamResult;
	import javax.xml.transform.stream.StreamSource;
	import org.springframework.context.ApplicationContext;
	import org.springframework.context.support.ClassPathXmlApplicationContext;
	import org.springframework.ws.WebServiceMessage;
	import org.springframework.ws.client.core.WebServiceMessageCallback;
	import org.springframework.ws.client.core.WebServiceTemplate;
	import org.springframework.ws.soap.SoapMessage;
	 
	/**
	 *
	 * @author PankajB
	 */
	public class Main {
	 
	    
	    /**
	     * @param args the command line arguments
	     */
	    public static void main(String[] args) {
	 
	        try
	        {
	   // Load the spring web service configuration file
	        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("springwsjxb/acjaxbb.xml");
	        WebServiceTemplate webServiceTemplate = (WebServiceTemplate)applicationContext.getBean("webServiceTemplate");      
	        // Creating the Request Object and setting it properties
	        CelsiusToFahrenheit celsiusToFahrenheit=new CelsiusToFahrenheit();
	        celsiusToFahrenheit.setCelsius(100);
	        // Invoking the web service and getting the response back.
	                CelsiusToFahrenheitResponse c=(CelsiusToFahrenheitResponse)webServiceTemplate.marshalSendAndReceive(celsiusToFahrenheit,new WebServiceMessageCallback() {
	 
	     // Setting the SOAP Action
	        public void doWithMessage(WebServiceMessage message) {
	            ((SoapMessage)message).setSoapAction("http://tempuri.org/CelsiusToFahrenheit");
	        }
	    });
	 
	 
	               System.out.println("THE RESPONSE From Web Service IS "+ c.getResult());
	 
	        }
	        catch(Exception ex)
	        {
	            ex.printStackTrace();
	        }
	    }
	 
	}


The code is pretty self explanatory, except at one point where we need to cast the object to our corresponding response, as the web service template does not provide any way to specify in the parameter list about the kind of response object we are expecting to receive.

Once it gets executed we will receive the result on to our console.
Someetimes our web servie is accessible only through HTTPS protocol, however the tried to just replace the URI Of my web services template, and it seems to work without any added configurtion. It might be possible that we need to install the certificate on our system either manually or through a software called PORTECLE.
So that's all for the time.
In the next part we will see how to create a web service through spring ws 2 and implement the same endpoint for both SOAP 1.1 & SOAP 1.2 i.e. we will not bother about whether client is invoking through text/xml or application/soap+xml (SOAP 1.2). Really Spring WS makes it so easy.
Thanks Arjen Postuma.
  相关解决方案