Posts Tagged ‘xmlbeans’
One entry point for several web services using Spring WS 1.0
Defining one entry point for every web service request in the system can be advisable in specific scenarios such as security based on URL ones. Below it’s described this kind of solution using Spring WS 1.0 as web service stack and XMLBeans 2 as marshalling method.
web.xml
Define desired URL (for instance, http://server/app/services/)
<!-- Defines the Spring-WS MessageDispatcherServlet -->
<servlet>
</servlet><servlet -name>spring-ws</servlet>
<servlet -class>
org.springframework.ws.transport.http.MessageDispatcherServlet
</servlet>
<init -param>
<!-- Transform the location attributes in WSDLs -->
<param -name>transformWsdlLocations</param>
<param -value>true</param>
</init>
<!-- Map all requests to this servlet -->
<servlet -mapping>
</servlet><servlet -name>spring-ws</servlet>
<url -pattern>/services/*</url>
applicationContext.xml
Configuration to get XMLObjects from XMLBeans unmarshalled at the endpoint.
<!-- EndPoint Mapping -->
<bean id="messageDispatcher"
class="org.springframework.ws.server.MessageDispatcher">
<property name="endpointMappings">
<list>
<ref local="payloadMapping" />
</list>
</property>
</bean>
<!-- Payload Mapping -->
<bean id="payloadMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
<property name="defaultEndpoint" ref="uniqueEndpoint" />
<!-- XSD validation can be specified -->
<property name="interceptors">
<list>
<ref local="validatingInterceptor" />
</list>
</property>
</bean>
<!-- XSD validation -->
<bean id="validatingInterceptor"
class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
<!-- Schemas repository folder -->
<property name="schemas" value="/WEB-INF/schemas/*.xsd" />
<property name="validateRequest" value="true" />
<property name="validateResponse" value="true" />
</bean>
<!-- Unique endpoint -->
<bean id="uniqueEndpoint" class="foo.bar.EndPoint">
<!-- XMLBeans marshalling (in & out) -->
<constructor -arg ref="xmlBeansMarshaller" />
</bean>
Endpoint Java Class
package foo.bar;
public class FCEEndPoint extends org.springframework.ws.server.endpoint.AbstractMarshallingPayloadEndpoint {
public FCEEndPoint(Marshaller marshaller) {
super(marshaller);
}
protected Object invokeInternal(Object requestObject) throws Exception {
XmlObject in = (XmlObject)requestObject;
// Retrieve operation name from some point of the incoming XML
String operationName = in.getDomNode().getFirstChild().getNodeValue();
// Generic invoker based on Java reflection
XmlObject out = OperationInvoker.invoke(operationName, in);
return out;
}
}
How it works?
In this way, new web services can be added by creating one XSD file and implementing its related business object. And clients only have to invoke the same URL for each request just only by using an appropiate XML.
Accessing XMLBeans by DOM
XMLBeans can be used to bind XML data from web services requests to Java beans. A JAR library containing this Java beans can be generated compiling XSD files with XMLBeans scomp utility. Once this Java beans are available on the system, XML attributes can be accessed using simple getters and setters from Java.
Besides, Spring WS provides a functionality in order to marshall XML incoming requests to XMLBeans extending AbstractMarshallingPayloadEndpoint class. Inside this method, XPath or DOM can be used to avoid reflection or casting.
public class EndPoint extends org.springframework.ws.server.endpoint.AbstractMarshallingPayloadEndpoint {
protected Object invokeInternal(Object requestObject) throws Exception {
XmlObject xo = (XmlObject)requestObject;
if (xo.getDomNode().getFirstChild().getFirstChild().getChildNodes().item(2).getFirstChild().getNodeValue().equals("A")) {
[...]
}
}
}
Imagine you have the same header defined on your XSD files for all incoming requests to your system. By making this you are able to read a fixed field from your XMLBeans without casting or reflecting.