Wednesday, March 28, 2012

Spring JMS tutorial

This tutorial is on Weblogic server.
before running this tutorial it is expected that Connection factory and queue JNDI is created on weblogic server.



  • This is Message listener bean

package com.test;

import javax.jms.Message;
import javax.jms.MessageListener;

public class SpringMDP implements MessageListener{
public void onMessage(Message message) {
if (MapMessage.class.isInstance(message)) {
     MapMessage mapMessage = (MapMessage)(message);
   }
}
}


  • This is the configuration for Message listner bean


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean id="messageListener" class="com.test.SpringMDP" />

<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
    <value>connectionFactoryJNDI</value>
</property>
  <property name="jndiTemplate">
    <ref bean="jndiTemplate" />
</property> 
</bean>

<bean id="queue" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
  <value>queueJNDI</value>
</property>
<property name="jndiTemplate">
  <ref bean="jndiTemplate" />
</property>
</bean>

  <bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer102">
    <property name="concurrentConsumers" value="5" />
   <property name="connectionFactory" ref="connectionFactory" />
    <property name="destination" ref="queue" />
   <property name="messageListener" ref="messageListener" />
</bean>
</beans>

  • This is a client Which publish the message

package com.test;

import java.util.Properties;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
import org.apache.log4j.Logger;

public class JMSClient {
    protected final static Logger log = Logger.getLogger(JMSClient.class);
    public  void publishmessage() {
    QueueConnection connection =null; 
    QueueSession qsession = null;
    try {
    Context jndiContext = getInitialContext();
    QueueConnectionFactory connFactory = (QueueConnectionFactory)jndiContext.lookup("connectionFactoryJNDI");
    Queue targetQueue = (Queue)jndiContext.lookup("queueJNDI");
    connection = connFactory.createQueueConnection();
    qsession = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    QueueSender sender = qsession.createSender(targetQueue);
    sender.setDeliveryMode(DeliveryMode.PERSISTENT);
    MapMessage message = qsession.createMapMessage();
    sender.send(message);
    }catch(Exception exp){
    log.error(exp.getMessage(), exp);

    }finally {
    if (qsession != null) {
    try{
    qsession.close();
    }catch(JMSException je){
    log.error(je.getMessage(), je);
    }
    }
    if (connection != null) {
    try {
    connection.close();
    }catch(JMSException je){
    log.error(je.getMessage(), je);
    }
    }
    }
    }
    public static InitialContext getInitialContext() throws javax.naming.NamingException {
        String url;
        url = "t3://localhost:7001";
        Properties h = new Properties();
        h.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
        h.put(Context.PROVIDER_URL, url);
        return( new InitialContext());
    }
}


Oracle PLSQL exception handling

For table structure follows my another blog  for oracle trigger example.

  • TOO_MANY_ROWS: When your select statement return multiple rows and that situation need to handle then you can use the TOO_MANY_ROWS exception.
  • OTHERS :  Others is a generic exception which will occur at bottom.
You can handle Exception within exception. If you knows JAVA exception handling then it is very easy to understand. It is almost work like JAVA exception handling.


Example

 CREATE OR REPLACE PROCEDURE EXCEPTION_TEST(test in VARCHAR2) AS
  EMP_NAME VARCHAR2(200);  
BEGIN
SELECT NAME  INTO EMP_NAME FROM TBL_EMPLOYEE;
EXCEPTION
WHEN TOO_MANY_ROWS THEN
BEGIN
SELECT NAME  INTO EMP_NAME FROM TBL_EMPLOYEE WHERE ID=1;
EXCEPTION
WHEN OTHERS THEN
EMP_NAME := 'NOT FOUND';
END;
WHEN OTHERS THEN
  EMP_NAME := 'NOT FOUND';
END EXCEPTION_TEST;

Monday, March 26, 2012

oracle trigger example

Oracle Trigger

  • Update Trigger: we will follow the belowexample
In this example I am created two tables employee and department. When employee change the department then one employee is deducted from his existing department and new employee is get added into new department.




CREATE TABLE TBL_DEPARTMENT (
ID NUMBER(10) primary key,
NAME     VARCHAR2(100),
EMPLOYEE_TOTAL  NUMBER(10));


CREATE TABLE TBL_EMPLOYEE (
ID NUMBER(10) primary key,
NAME     VARCHAR2(100),
DESIGNATION  VARCHAR2(100),
DEPARTMENT_ID  NUMBER(10),
CONSTRAINT "TBL_EMPLOYEE _FK"  FOREIGN KEY ("DEPARTMENT_ID")
REFERENCES "TBL_DEPARTMENT" ("ID") ENABLE);


insert into TBL_DEPARTMENT (ID,NAME,EMPLOYEE_TOTAL) values(1,'Account',5);
insert into TBL_DEPARTMENT (ID,NAME,EMPLOYEE_TOTAL) values(2,'Admin',2);
insert into TBL_EMPLOYEE (ID,NAME,DESIGNATION, DEPARTMENT_ID) values(1,'Mr. Employess','Manager',1);


CREATE OR REPLACE TRIGGER TR_EMPLOYEE_UPDATE
BEFORE UPDATE ON TBL_EMPLOYEE
FOR EACH ROW
DECLARE
BEGIN
      IF(:OLD.DEPARTMENT_ID != :NEW.DEPARTMENT_ID) THEN
      UPDATE TBL_DEPARTMENT set EMPLOYEE_TOTAL = EMPLOYEE_TOTAL+1 where ID = :NEW.DEPARTMENT_ID;
        UPDATE TBL_DEPARTMENT set EMPLOYEE_TOTAL = EMPLOYEE_TOTAL-1 where ID = :OLD.DEPARTMENT_ID;
      END IF;
END TR_EMPLOYEE_UPDATE;


select * from tbl_department;
update tbl_employee set department_id=2 where id=1;
select * from tbl_department ;


 If you check the employee count of the department  before and after the update query for department then you can realize the difference.




  • Insert Trigger : We will continue above example, suppose we add new employee,  our corresponding department count will increase automatically.
CREATE OR REPLACE TRIGGER TR_EMPLOYEE_INSERT
AFTER INSERT ON TBL_EMPLOYEE
FOR EACH ROW
DECLARE
BEGIN
      UPDATE TBL_DEPARTMENT set EMPLOYEE_TOTAL = EMPLOYEE_TOTAL+1 where ID = :NEW.DEPARTMENT_ID;
END 
TR_EMPLOYEE_INSERT ;

select * from tbl_department;
insert into TBL_EMPLOYEE (ID,NAME,DESIGNATION, DEPARTMENT_ID) values(2,'Mr. Employess New','Ass. Manager',1);
select * from tbl_department ;
Execute the above statement in sequence then just compare the output of department count before and after the employee insert statement.




  • Delete Trigger : For delete also we will continue with same example , suppose we delete some employee from our database then the corresponding department count will be deducted by 1.
CREATE OR REPLACE TRIGGER TR_EMPLOYEE_DELETE
BEFORE DELETE ON TBL_EMPLOYEE
FOR EACH ROW
DECLARE
BEGIN
      UPDATE TBL_DEPARTMENT set EMPLOYEE_TOTAL = EMPLOYEE_TOTAL-1 where ID = :OLD.DEPARTMENT_ID;
END TR_EMPLOYEE_DELETE;


select * from tbl_department;
delete from tbl_employee where id = 2;
select * from tbl_department;


Execute the above statement in sequence then just compare the output of department count before and after the employee delete statement.

Wednesday, March 21, 2012

Spring WebService Tutorial

I tested this tutorial on following configuration
 JDK1.7
Tomcat 7.0
Maven-3.0.3


Folder structure
  • Integration-springWS
    • Properties
      • dev.properties
    • src
      • main
        • java
          • com
            • test
              • BasicEndpointCommand.java
              • EndpointPointCommand.java
              • NotificationEndpoint.java
              • ObjectFactory.java
              • UserRequestType.java
              • UserResponseType.java
        • resources
          • log4j.properties
        • webapp
          • WEB-INF
            • notification.xsd
            • psring-ws-servlet.xml
            • web.xml
          • index.htm
      • test
    • pom.xml
    • tomcat-deploy.sh
dev.properties

LOG_LEVEL=debug
LOG_FILE_DIR=springWS_log

BasicEndpointCommand.java



package com.test;
import java.util.Date;
import java.util.Map;
import org.apache.log4j.Logger;


/**
 * Description:
 * @author Sandeep
 */


public class BasicEndpointCommand implements EndpointPointCommand {


private static final Logger log = Logger.getLogger(BasicEndpointCommand.class);

@SuppressWarnings("unchecked")
@Override
public Object execute(Map info) throws Exception {
if (log.isDebugEnabled()) {
log.debug("TIME::" + new Date());
log.debug("INFO::" + info);
}
return null;
}
}



EndpointPointCommand.java



package com.test;
import java.util.Map;

/**
 * @author Sandeep
 */
public interface EndpointPointCommand {
@SuppressWarnings("unchecked")
public Object execute(Map info) throws Exception;
}

NotificationEndpoint.java




package com.test;




import java.util.HashMap;
import java.util.List;
import java.util.Map;


import javax.xml.bind.JAXBElement;


import org.apache.log4j.Logger;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;


/**
 * @author Sandeep 
 */
@Endpoint
public class NotificationEndpoint {

public static final String KEY_USERID = "KEY_USERID";
public static final String KEY_USERNAME = "KEY_USERNAME";

private List commands;
private static final Logger log = Logger.getLogger(NotificationEndpoint.class);
@PayloadRoot(localPart = "userRequest", namespace = "http://www.stack-over-flow.blogspot.com/schema")
    public JAXBElement user(JAXBElement requestElement) throws Exception {

UserResponseType responseType = new UserResponseType();
UserRequestType request = requestElement.getValue();
try{
Map info = new HashMap();

info.put(KEY_USERID, request.getUserId());
info.put(KEY_USERNAME, request.getUserName());


log.debug("INFO ::"+info );

for(EndpointPointCommand command: commands){
command.execute(info);
}

}catch(Exception e){
responseType.setSuccessful(false);
responseType.setError(e.getMessage());
}

responseType.setSuccessful(true);
return new ObjectFactory().createUserResponse(responseType);
}


public List getCommands() {
return commands;
}


public void setCommands(List commands) {
this.commands = commands;
}
}


ObjectFactory.java




package com.test;


import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;




@XmlRegistry
public class ObjectFactory {


    private final static QName _UserResponse_QNAME = new QName("http://www.stack-over-flow.blogspot.com/schema", "userResponse");
    private final static QName _UserRequest_QNAME = new QName("http://www.stack-over-flow.blogspot.com/schema", "userRequest");


    public ObjectFactory() {
    }


    /**
     * Create an instance of {@link DaEventNotificationRequestType }
     * 
     */
    public UserRequestType createUserRequestType() {
        return new UserRequestType();
    }


    /**
     * Create an instance of {@link DaEventNotificationResponseType }
     * 
     */
    public UserResponseType createUserResponseType() {
        return new UserResponseType();
    }


    /**
     * Create an instance of {@link JAXBElement }{@code <}{@link DaEventNotificationResponseType }{@code >}}
     * 
     */
    @XmlElementDecl(namespace = "http://www.stack-over-flow.blogspot.com/schema", name = "userResponse")
    public JAXBElement createUserResponse(UserResponseType value) {
        return new JAXBElement(_UserResponse_QNAME, UserResponseType.class, null, value);
    }


    /**
     * Create an instance of {@link JAXBElement }{@code <}{@link DaEventNotificationRequestType }{@code >}}
     * 
     */
    @XmlElementDecl(namespace = "http://www.stack-over-flow.blogspot.com/schema", name = "userRequest")
    public JAXBElement createUserRequest(UserRequestType value) {
        return new JAXBElement(_UserRequest_QNAME, UserRequestType.class, null, value);
    }


}



UserRequestType.java

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2012.03.06 at 09:16:46 AM GST 
//


package com.test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.XMLGregorianCalendar;


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "UserRequestType", propOrder = {

})
public class UserRequestType {

    protected int userId;
    @XmlElement(required = true)
    protected String userName;

    public int getUserId() {
        return userId;
    }

    public void setUserId(int value) {
        this.userId = value;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String value) {
        this.userName = value;
    }
}

UserResponseType.java

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-833 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2012.03.06 at 09:16:46 AM GST 
//

package com.test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "UserResponseType", propOrder = {

})
public class UserResponseType {
    protected boolean successful;
    protected String error;
    public boolean isSuccessful() {
        return successful;
    }
    public void setSuccessful(boolean value) {
        this.successful = value;
    }
    public String getError() {
        return error;
    }
    public void setError(String value) {
        this.error = value;
    }
}

log4j.properties

# Log4J logging properties

log4j.rootLogger=error, File

###### File appender definition #######
log4j.appender.File=org.apache.log4j.DailyRollingFileAppender
log4j.appender.File.File=integration-springws.log
log4j.appender.File.Append=true
log4j.appender.File.layout=org.apache.log4j.PatternLayout
log4j.appender.File.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c{3}] %m%n

# logger level
log4j.logger.org.apache.commons=warn
log4j.logger.org.apache.cxf=warn
log4j.logger.org.springframework=warn
log4j.logger.javax.xml.bind=warn

notification.xsd


<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified"
xmlns="http://www.stack-over-flow.blogspot.com/schema" targetNamespace="http://www.stack-over-flow.blogspot.com/schema">
<xs:element name="userRequest" type="UserRequestType" />
<xs:element name="userResponse" type="UserResponseType" />
<xs:complexType name="UserRequestType">
<xs:annotation>
<xs:documentation></xs:documentation>
</xs:annotation>
<xs:all>
<xs:element name="userId" type="xs:int" />
<xs:element name="userName" type="xs:string" />
</xs:all>
</xs:complexType>
<xs:complexType name="UserResponseType">
<xs:all>
<xs:element name="successful" type="xs:boolean" minOccurs="1" />
<xs:element name="error" type="xs:string" minOccurs="0" />
</xs:all>
</xs:complexType>
</xs:schema>


spring-ws-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>



<beans xmlns="http://www.springframework.org/schema/beans" 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-2.0.xsd">
<bean id="notificationEndpoint" class="com.test.NotificationEndpoint">
        <property name="commands">
        <list>
        <ref local="basicCommand"/>
        </list>
        </property>
    </bean>
    <bean id="basicCommand" class="com.test.BasicEndpointCommand"/>
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping"/>
<bean class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter">
<constructor-arg ref="marshaller" />
</bean>
<bean id="notification" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
    <property name="schema" ref="schema"/>
    <property name="portTypeName" value="UserNotification"/>
    <property name="locationUri" value="Integration-springws/spring-ws/notificationService"/>
    <property name="targetNamespace" value="http://www.stack-over-flow.blogspot.com/schema"/>
</bean>
<bean id="schema" class="org.springframework.xml.xsd.SimpleXsdSchema">
    <property name="xsd" value="/WEB-INF/notification.xsd"/>
</bean>
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="com.test" />
</bean>
</beans>


web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">
    <display-name>Archetype Created Web Application</display-name>
    <servlet>
        <servlet-name>spring-ws</servlet-name>
        <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-ws</servlet-name>
        <url-pattern>/spring-ws/*</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
    <welcome-file>index.htm</welcome-file>
    </welcome-file-list>
</web-app>
Index.htm

<html>
<title>Spring WS Endpoint</title>
<head></head>
<body>
To see WSDL see following link<p>
<a href="spring-ws/notificationService/notification.wsdl">wsdl<a/>
<body>
</html>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Integration-springws-test</groupId>
<artifactId>Integration-springws</artifactId>
<version>1.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>notification-endpoint Spring-WS Application</name>
<url>http://www.springframework.org/spring-ws</url>
<build>
<finalName>Integration-springws</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<configuration>
<server>myserver</server>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${buildNumber}</Implementation-Build>
</manifestEntries>
</archive>
</configuration>
</plugin>
   </plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<!-- <scope>test</scope> -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>2.5.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.9</version>
</dependency>
<dependency>
    <groupId>commons-configuration</groupId>
    <artifactId>commons-configuration</artifactId>
    <version>1.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>oracle</id>
<name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name>
<url>http://www.mvnsearch.org/maven2/</url>
</repository> 
</repositories>
</project>
tomcat-deploy.sh

pid=`ps -aef | grep tomcat | grep -v grep | awk '{print $2}'`

if [ -n "$pid" ]; then 

  echo 'About to kill:' $pid

  kill -9 `ps -aef | grep tomcat | grep -v grep | awk '{print $2}'`
else
  echo 'No tomcat running.'
fi
rm -rf $TOMCAT_HOME/webapps/*Integration-springws*
cp ./target/Integration-springws.war $TOMCAT_HOME/webapps
$TOMCAT_HOME/bin/startup.sh

after this just open the browser and type following URL in the browser

http://localhost:8080/Integration-springws/

Monday, March 19, 2012

Adding SOAP Header element


Example for adding the SOAP Header element
For adding Version element in the SOAP header. Then final header will look like this.


<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<SOAP-ENV:Header>
  <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
  <Version xmlns="http://stack-over-flow.blogcpot.com/schema">1.1</Version>
  </SOAP-ENV:Header><SOAP-ENV:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-615">
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>


When you are formatting your request at client side then you can add the following code for creation of header element.
soapMessage.getSoapHeader().addHeaderElement(new QName(" http://stack-over-flow.blogcpot.com /schema","Version")).setText("1.1");

It will add the SOAP header as shown in the example above


When you sent the request at server side if you want to access the header element from the request you can add interceptor like SoapEndpointInterceptor


add the following code in your customize interceptor 


import java.util.regex.Matcher;
import java.util.regex.Pattern;

private static final Pattern versionNamePattern = Pattern.compile("<Version xmlns=\" http://stack-over-flow.blogcpot.com/schema\">(.*)</Version>");
matcher = versionNamePattern.matcher(soapMessageText);
String version = (matcher.find())?matcher.group(1):null;







Spring-WS schema validation using PayloadValidatingInterceptor

PayloadValidatingInterceptor Configuration
when web service type is contract first development then one can use the Interceptor for validation the schema. Spring-WS supports PayloadValidatingInterceptor which is use for validate both request and response.
There are multiple ways to implement the schema validation.

  • Spring-WS schema Validation

<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">

 < property name="interceptors">
< list>
< ref bean="validatingInterceptor"/ > 
< /list>
 < /property>
< /bean>

<bean id="validatingInterceptor" class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
    <property name="schema" value="/jaxb/test.xsd"/>
    <property name="validateRequest" value="true"/>
    <property name="validateResponse" value="true"/>
</bean>


  • Customize schema validation


 <bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
 < property name="interceptors">
 < list>
 < ref bean="validatingInterceptor"/ > 
 < /list>
 < /property>
 < /bean>

<bean id="validatingInterceptor" class="com.test.ValidationInterceptor ">
     <property name="schema" value="/jaxb/test.xsd"/>
</bean>


we can customize the the Spring configuration by extending the spring Interceptor class.

  • In customization you can use your own Validator
  • you can customize your Exception handling and SOAP Fault handling in schema Validation.

package com.test;

import java.io.StringWriter;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.dom.DOMResult;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.apache.log4j.Logger;
import org.springframework.core.io.ResourceLoader;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.soap.client.SoapFaultClientException;
import org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor;
import org.xml.sax.SAXException;

public class ValidationInterceptor extends PayloadValidatingInterceptor{
private ResourceLoader resourceLoader;
private static final Logger log = Logger.getLogger(ValidationInterceptor.class);
protected Source getValidationRequestSource(WebServiceMessage request){
Source source =null;
try{
source =request.getPayloadSource();
validateSchema(source);
}catch(SoapFaultClientException soapException){
log.debug("SOAP Fault "+soapException.getMessage());
soapException.printStackTrace();
}catch(Exception ex){
log.debug("Exception "+ex.getMessage());
ex.printStackTrace();
}
return source;
}

private void validateSchema(Source source) throws Exception{
SchemaFactory schemaFactory = SchemaFactory.newInstance(getSchemaLanguage());
Schema schema = schemaFactory.newSchema(getSchemas()[0].getFile());
Validator validator = schema.newValidator();
DOMResult result = new DOMResult();
try {
validator.validate(source, result); 
} catch (SAXException ex) {
setFaultStringOrReason(ex.getLocalizedMessage());
}
}

public ResourceLoader getResourceLoader() {
return resourceLoader;
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}