Workshop 9
Workshop 9
Workshop 9
RMI facilitates writing distributing applications using Java programming language. With
RMI, object on one machine call call method on different machine. RMI uses the Java
Remote Method Protocol (JRMP) for remote Java object communication.
Spring provides four ways to develop remote services. Remote services are services
hosted on remote servers and accessed by clients over the network.
1. RMI - Remote Method Invocation - Use RMI to invoke a remote method. The java
objects are serialized
2. Hessian - Transfer binary data between the client and the server.
3. Burlap - Transfer XML data between the client and the server. It is the XML
alternative to Hessian
4. JAX-WS - Java XML API for Web Services.
Sample Application:
Server Side:
1. In Elcipse, Create a Java Project named RMIServer, Convert it into maven,
Create a package named myserver and put following java files inside it and do
the following:
2. Create an interface namely MyRmiService.java as following
package myserver;
import java.rmi.Remote;
import java.rmi.RemoteException;
Note: To Compile this file, opem command prompt go to src directory and
type javac myserver\RmiService.java
1
3. Create MyRmiImpl.java as following:
package myserver;
Note: To Compile this file, opem command prompt go to src directory and
type javac myserver\RmiImpl.java
2
5. Put following codes inside pom.xml file
<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>RMIServer</groupId>
<artifactId>RMIServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<spring.version>4.2.5.RELEASE</spring.version>
</properties>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
6. Create MyRmiServer.java as following:
package myserver;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationCont
ext;
3
try
{
ApplicationContext context1=new
ClassPathXmlApplicationContext("iiop.xml");
System.out.println("Waiting for Request from
Client ...");
}
catch(Exception e)
{
e.printStackTrace();
}
}
Note: To Compile this file, opem command prompt go to src directory and
type javac myserver\RmiServer.java
Client Side:
1. In Elcipse, Create a Java Project named RMIClient, Convert it into maven and do
the following:
2. Put the following codes inside pom.xml file
<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>RMIServer</groupId>
<artifactId>RMIServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<spring.version>4.2.5.RELEASE</spring.version>
</properties>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
4
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
<bean id="greetingService"
class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://localhost:1099/rmiService"/>
<property name="serviceInterface" value="rmiserver.MyRmiService"/>
</bean>
</beans>
5
4. Inside src folder create a package named rmiclient and create MyRmiClient.java
inside it:
package rmiclient;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
import rmiserver.MyRmiService;
}
5. Create a package namely rmiserver and create MyRmiService.java inside it
package rmiserver;
RMI-IIOP
IIOP stands for Internet Inter-ORB Protocol. IIOP is CORBA's communication protocol.
It defines the way the bits are sent over a wire between CORBA clients and servers.
CORBA is a standard distributed object architecture developed by the Object
Management Group (OMG).
Previously Java programmers had to choose between RMI and CORBA/IIOP (Java IDL)
for distributed programming solutions. Now, by adhering to a few restrictions, RMI
objects can use the IIOP protocol, and communicate with CORBA objects. This solution
6
is known as RMI-IIOP. RMI-IIOP combines RMI-style ease of use with CORBA cross-
language interoperability.
RMI over IIOP (RMI-IIOP hereafter), developed jointly by IBM and Sun, is a new version
of RMI (Remote Method Invocation) for IIOP (Internet Inter-ORB Protocol) that
combines RMI's easy programming features with CORBA's interoperability.
Sample Application:
We are not going to use Eclipse for creating sample application that uses RMI-IIOP
because there is difficultly on creating stub and tie classes in eclipse.
Add following jar files into classpath environment variables. Sample classpath variable
values for various jars required for the application is:
.;D:\Spring_Materials\Installation\spring-framework-4.2.2.RELEASE\libs\spring-context-
4.2.2.RELEASE.jar;.;D:\Spring_Materials\Installation\spring-framework-4.2.2.RELEASE\
libs\spring-core-4.2.2.RELEASE.jar;.;D:\Spring_Materials\Installation\spring-framework-
4.2.2.RELEASE\libs\spring-beans-4.2.2.RELEASE.jar;.;d:\jars\commons-logging-
1.2.jar;.;d:\jars\spring-expression-4.2.5.RELEASE.jar;.;d:\jars\spring-aop-
4.2.5.RELEASE.jar;.;d:\jars\aopalliance-1.0.jar
Project Folder:
Inside D:\drive create folder named rmiiiop and within this folder create two sub folders
namely myserver and myclient.
Server Side:
Within myserver package, create following files:
1. Interface file namely MyRmiService.java:
package myserver;
import java.rmi.Remote;
import java.rmi.RemoteException;
Note: To compile this file open command prompt and stay on rmiiiop
directory and issue javac rmiserver\MyRmiService.java command
7
2. Implementaton file namely MyRmiImpl.java
package myserver;
import java.rmi.RemoteException;
public class MyRmiImpl implements MyRmiService {
Note: To compile this file open command prompt and stay on rmiiiop
directory and issue javac rmiserver\MyRmiImpl.java command
package myserver;
import java.io.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
try
{
ApplicationContext context1=new
ClassPathXmlApplicationContext("file:D:/rmiiiop/myserver/iiop.xml");
System.out.println("Waiting for Request from Client ...");
}
catch(Exception e)
{
e.printStackTrace();
}
}
8
}
Note: To compile this file open command prompt and stay on rmiiop
directory and issue javac rmiserver\MyRmiServer.java command
<bean class="org.springframework.remoting.rmi.JndiRmiServiceExporter">
<property name="jndiName" value="HelloWorld"/>
<property name="serviceInterface" value="myserver.MyRmiService" />
<property name="service" ref="rmiService"/>
<property name="jndiEnvironment">
<props>
<prop key="java.naming.factory.initial">
com.sun.jndi.cosnaming.CNCtxFactory
</prop>
<prop
key="java.naming.provider.url">iiop://192.168.100.4:7886</prop>
</props>
</property>
</bean>
</beans>
5. To Generate stub and Tie files required, open command prompt, stay on rmiiiop
directory and issue following command:
9
6. Staying on rmiiiop directory type following command to start server application
java myserver.MyRmiServer
Client Side:
Within myclient package create following files:
1. Application context file namely iiop-client.xml
<bean id="rmiService"
class="org.springframework.remoting.rmi.JndiRmiProxyFactoryBean">
<property name="jndiName" value="HelloWorld" />
<property name="serviceInterface" value="myserver.MyRmiService" />
<property name="jndiEnvironment">
<value>
java.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
java.naming.provider.url=iiop://192.168.100.4:7886
</value>
</property>
</bean>
</beans>
2. MyRmiClient.java
10
package myclient;
import java.io.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import myserver.MyRmiService;
public class MyRmiClient {
try
{
ApplicationContext context=new
ClassPathXmlApplicationContext("file:D:/rmiiiop/myserver/iiop-client.xml");
MyRmiService obj=(MyRmiService)context.getBean("rmiService");
int result=obj.add(12,15);
System.out.println("Result="+result);
System.out.println("Waiting for Request from Client ...");
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Note: To Compile this file, type javac myclient\RmiClient.java command
staying on rmiiiop directory
3. Staying on rmiiiop directory, type the following command to start the client
application:
java myclient.MyRmiClient
References:
1. http://www.nyu.edu/classes/jcf/g22.3033-003_fa09/handouts/
g22_3033_011_h4c.htm
2. http://www.javaworld.com/article/2076547/soa/rmi-over-iiop.html
3. http://www.studytrails.com/frameworks/spring/spring-remoting-rmi.jsp
11
Hessian Service
he Hessian binary web service protocol is a powerful and easy-to-use alternative
to RMI, XML/SOAP, and REST/JSON for remote communication.
Hessian is a web service protocol that transfers binary data between a remote
service and its client. Hessian has been released by Caucho Technology. It
requires that the web service be hosted on an http server. The client uses HTTP
protocol to invoke remote methods on the server. The important classes are : -
org.springframework.remoting.caucho.HessianServiceExporter - This
exports the specified service as a servlet based http request handler. Hessian
services exported by this class can be accessed by any hessian client.
org.springframework.remoting.caucho.HessianProxyFactoryBean - This is
the factory bean for Hessian clients. The exposed service is configured as a
spring bean. The ServiceUrl property specifies the URL of the service and
the ServiceInterface property specifies the interface of the implemented service.
Sample Application:
Server Side:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
12
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
3. Add DispatcherServelt named hessian into the project[ Right Click Project-
>New->Servlet->Choose an Existing Servlet-> Click on DispatcherServlet
from the list-> Give it the name “hessian”.
4. Create a package namely myserver within src and create following two java
files within it
5. Put following source code inside MyHessianService.java
package myserver;
import org.springframework.remoting.caucho.HessianServiceExporter;
public interface MyHessianService {
public int add(int a,int b);
}
13
6. Put following source code inside MyHessianServiceImpl.java
package myserver;
@Override
public int add(int a, int b) {
// TODO Auto-generated method stub
return (a+b);
}
<bean name="/hessianService.http"
class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="hessianService" />
<property name="serviceInterface" value="myserver.MyHessianService"/>
</bean>
</beans>
14
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>hessian</display-name>
<servlet-name>hessian</servlet-name>
<servlet-
class>org.springframework.web.servlet.DispatcherServlet</servlet-
class>
</servlet>
<servlet-mapping>
<servlet-name>hessian</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
9. Run the project on server-> Right Click HessianServer->Run As-> Run on
Server.
Client Side:
1. Inside src package create a package named “myclient” and create a Java file
named MyHessianClient.java inside it.
package myclient;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContex
t;
import com.caucho.hessian.client.HessianProxyFactory;
import
org.springframework.remoting.caucho.HessianProxyFactoryBean;
import myserver.MyHessianService;
15
2. Create a file named spring-config-client.xml inside src folder as following:
xsi:schemaLocation="http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-
4.0.xsd">
<bean id="hessianService"
class="org.springframework.remoting.caucho.HessianProxyFactoryBea
n">
<property name="serviceUrl"
value="http://localhost:8080/HessianServer/hessianService.http"/>
<property name="serviceInterface"
value="myserver.MyHessianService"/>
</bean>
</beans>
Reference
1. http://www.studytrails.com/frameworks/spring/spring-remoting-hessian.jsp
16
Burlap
Burlap is another remoting protocol supported by Spring. Burlap is an XML based
protocol for web services. It has been developed by Caucho. It is similar to Hessian, the
only difference being Hessian is binary and Burlap is XML. Like Hessian, Burlap needs
to be hosted over HTTP. Similar to Hessian, it has a BurlapServiceExporter and a
BurlapProxyFactoryBean class. Note that since Burlap is not being actively developed,
its support has been deprecated since Spring 4.0.
Sample Application:
Server Side:
1. Create a Dynamic Web Project named BurlapDemo, Convert it into Maven
Project[ Right Click BurlapDemo->Configure-> Convert to Maven Project
2. Your pom.xml file should contain following source code:
<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>BurlapDemo</groupId>
<artifactId>BurlapDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<spring.version>4.2.5.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.38</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<build>
17
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
3. Add DispatherServlet namely burlap into your project
4. Inside src create a package namely myserver and create two java files namely
MyBurlapService.java and MyBurlapServiceImpl.java
5. MyBurlapService.java should contain following codes:
package myserver;
@Override
public int add(int a, int b) {
// TODO Auto-generated method stub
return (a+b);
}
}
18
7. Inside WebContent/WEB-INF folder create an XML file namely burlap-servlet.xml
as following:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean name="/burlapService.http"
class="org.springframework.remoting.caucho.BurlapServiceExporter">
<property name="service" ref="burlapService" />
<property name="serviceInterface" value="myserver.MyBurlapService"/>
</bean>
</beans>
19
9. Right Click BurlapDemo->Run As ->Run on Server
Client Side:
1. Inside src package create a folder namely myclient and create a file namely
MyBurlapClient.java inside it as following:
package myclient;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContex
t;
import myserver.MyBurlapService;
20
HTTP Invoker Service
HttpInvoker is another remoting protocol supported by spring framework. HttpInvoker
combines the ease of Hessian and Burlap, in that it is very easy to set up. It serializes
and deserializes java object for trasport over the network. However, probably the only
drawback is that Http Invoker is bound to java and hence the clients all need to be java
based. This is the recommended choice for remoting for java-java based
communication. The main classes are:
org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter -
This is a servlet API based Http request handler. It is used to export the remote
services. It takes in a service property that is the service to be exported and
a ServiceInterface that specifies the interface that the service is tied to.
org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean -
This is a proxy factory for creating http invoker proxies. It has
aserviceUrl property that must be an http url exposing an http invoker service.
This class serializes the objects that are sent to remote services and deserializes
the objects back.
Sample Application:
Server Side:
1. Create a Dynamic Web Project namely HttpInvokerDemo and convert it into
Maven Project
2. Your pom.xml file should contain following codes:
<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>HttpInvokerDemo</groupId>
<artifactId>HttpInvokerDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<spring.version>4.2.5.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.38</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
21
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
3. Add a DispatcherServlet namely httpinvoker into your project
4. Your web.xml file should contain following codes:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID"
version="2.5">
<display-name>HttpInvokerDemo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>httpinvoker</display-name>
<servlet-name>httpinvoker</servlet-name>
22
<servlet-class>org.springframework.web.servlet.DispatcherServlet</
servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>httpinvoker</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
5. Inside src create a package namely myserver and create two java files inside it:
HttpInvokerService.java and HttpInvokerServiceImpl.java
6. HttpInvokerService.java should contain following codes:
package myserver;
package myserver;
public class HttpInvokerServiceImpl implements
HttpInvokerService{
@Override
public int add(int a, int b) {
// TODO Auto-generated method stub
return (a+b);
}
<bean name="/httpinvokerService.http"
23
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExpor
ter">
<property name="service" ref="httpinvokerService" />
<property name="serviceInterface" value="myserver.HttpInvokerService"/>
</bean>
</beans>
}
}
24
Reference:
1. http://www.studytrails.com/frameworks/spring/spring-remoting-http-invoker.jsp
25
<groupId>org.jvnet.jax-ws-commons.spring</groupId>
<artifactId>jaxws-spring</artifactId>
<version>1.8</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.xml.stream.buffer</groupId>
<artifactId>streambuffer</artifactId>
</exclusion>
<exclusion>
<groupId>org.jvnet.staxex</groupId>
<artifactId>stax-ex</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. Create a package named myserver inside JavaResources/src folder and create
two java files namely MyWS.java and MyWSImpl.java inside it
3. MyWS.java should contain following codes:
package myserver;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
@WebService
26
@SOAPBinding(style = Style.RPC)
public interface MyWS {
@WebMethod public int add(int a,int b);
}
package myserver;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService(endpointInterface = "myserver.MyWS")
public class MyWSImpl implements MyWS{
@Override
public int add(int a, int b) {
// TODO Auto-generated method stub
return (a+b);
}
}
</beans>
27
Note: Do not worry about the mistake if your eclipse editor highlights error
here
<display-name>Spring + JAX-WS</display-name>
<servlet>
<servlet-name>jaxws-servlet</servlet-name>
<servlet-class>
com.sun.xml.ws.transport.http.servlet.WSSpringServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jaxws-servlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
http://localhost:8080/JAXWSDemo/hello?wsdl
28
Client Side:
1. Create a package namely myclient and create a java file named
MyWSClient.java as shown below:
package myclient;
import java.net.URL;
import javax.xml.ws.Service;
import myserver.MyWS;
import myserver.MyWSImpl;
import javax.xml.namespace.QName;
}
Note: the first parameter of QName is Service URI and second parameter is
ServiceName, that you have to determine looking at wsdl file
29
REST Service
We can develop Web Service either using SOAP or REST. In following example, we are
going to develop REST based web service using Apache CXF.
REST is not a technology and certainly is not a standard of some kind. It is merely an
architectural style that tells how to write a web service in a certain way.
Main Component of REST architecture is a Resource which can be uniquely identified
by an Uniform Resource Identifier or URI. State of a resource at any given point of time
is represented by a document and is called Representation of resource. The client can
update the state of resource by transferring the representation along with the request.
The new representation is now returned to client along with the response. The
representation contains the information in formats like html, xml, JSON etc that is
accepted by the resource. The resource which adheres to rules of REST architecture is
called a RESTfull resource and web service that adheres to this rule are called RESTfull
web service.
Sample Application:
1. Create a Dynamic Web Project named ApacheCXF and convert it into the maven
project, add following dependency information in pom.xml file
<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>ApacheCXF</groupId>
<artifactId>ApacheCXF</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<spring.version>4.0.0.RELEASE</spring.version>
<cxf.version>3.0.0</cxf.version>
<jackson.version>2.0.1</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf.version}</version>
30
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. Create a package named myserver inside Java Resources/src and within this
package create three Java files namely MyInterface.java,MyImpl.java and
MyModel.java
3. Put following source code inside MyModel.java
package myserver;
public class MyModel {
int id;
String name;
31
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
package myserver;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@Path("/example")
@Produces("application/json")
public interface MyInterface {
@GET
@Path("/{id}")
public MyModel method(@PathParam("id") int id);
}
package myserver;
import org.springframework.stereotype.Service;
@Service("exampleService")
public class MyImpl implements MyInterface {
@Override
public MyModel method(int id) {
// TODO Auto-generated method stub
return new MyModel(id,"mukesh");
}
32
6. Inside WebContent/WEB-INF folder, create an XML file namely spring-cxf-rest-
example.xml
</beans>
33
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-cxf-rest-example.xml</param-value>
</context-param>
<listener>
<listener-
class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
8. Right Click your Project[ApacheCXF]-> Run As-> Run On Server
9. Type following URL on google chrome after completing above step 8.
http://localhost:8080/ApacheCXF/services/example/1
Reference
1. https://www.javacodegeeks.com/2013/07/developing-restful-services-using-
apache-cxf.html
34
Invoking EJB Components using Spring
EJB stands for Enterprise Java Beans(EJB). We will develop a Spring MVC program
that will access EJB beans. So, let us develop a sample application program that will
first of all expose EJB bean for remote access and later on we will develop a Spring
MVC client program that will access EJB bean
EJB Application
Enterprise Java Bean is Deployed on Web Server called JBOSS. The recent version of
JBOSS that supports JDK 1.8 is AddFly 10.0. Hence, you must have to install JBOSS
plugin and AddFly in order for your application program to run.
1. Create EJB Application Project named “MyEJBApp” [ File-> New-> Other-> EJB
Project
35
[In order to Add WildFly 10.0, Click on New Runtime-> Click on Show Additional
Server Adapters-> Click on JBOSS Application Server AS-> Wait for a couple of
minutes JBoss will be installed eventually]-> Click on Wildfly 10.0 Runtime->
Click on Download and Install Run Time->Make sure JDK 1.8 and JRE 1.8 are
selected-> Click on Next]
2. Make sure that Generate ejb-jar-xml is checked.
import javax.ejb.Remote;
@Remote
public interface HelloWorld {
public String sayHello();
}
36
5. Inside ejbModule folder create a package named myejb.businesslogic and create
an implementation file knows as HelloWorldBean.java as shown below:
package myejb.businesslogic;
import javax.ejb.Stateless;
import myejb.business.HelloWorld;
/**
* Session Bean implementation class HelloWorldBean
*/
@Stateless
public class HelloWorldBean implements HelloWorld {
/**
* Default constructor.
*/
public HelloWorldBean() {
// TODO Auto-generated constructor stub
}
@Override
public String sayHello() {
// TODO Auto-generated method stub
return "Hello World !";
}
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port = 8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONY
MOUS=false
7. Add jboss-client.jar in both Java Build Path and Deployment Assembly of your
project.
8. Right Click MyEJBApp-> Run As-> Select WildFly 10.0->Select MyEjbApp->
Click on Finish
37
Spring MVC Application to invoke EJB Bean
The below Spring Application will call sayHello( ) method of HelloWorldBean class from
Controller.
1. Create a Dynamic Web Project named SpringEJBClient, convert it into the
Maven Project and make sure its pom.xml file has following codes in it:
<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>SpringEJBClient</groupId>
<artifactId>SpringEJBClient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<spring.version>4.2.5.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- Spring dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
38
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. You have to Add MyEJBApp project to both Java Build Path and Deployment
Assembly. [Right Click on SpringEJBClient->Build Path->Configure Build Path-
>Java Build Path-> Click on Projects Tab-> Click on Add Button-> Check
MyEJBApp project-> Click on Apply]. In order to Add the same project to
Deployment Assembly[ Click on Deployment Assembly-> Click on ADD-> Click
on Next-> Select MyEJBApp-> Click on Apply-> Click on OK].
3. Inside Java Resources/src folder create a package named controller and create
a controller class named HelloWorldController.java inside it:
package controller;
import javax.ejb.EJB;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import myejb.business.HelloWorld;
import myejb.clientutil.ClientUtility;
@Controller
public class HelloWorldController {
public HelloWorld hellowld=lookupHelloWorldBean();
@RequestMapping("/hello")
39
public String hello(@RequestParam(value="name", required=false,
defaultValue="World") String name, Model model) {
model.addAttribute("name", name);
model.addAttribute("ejbstest", hellowld.sayHello());
//returns the view name
return "helloworld";
40
5. Inside WebContent/WEB-INF, create a folder named views and create a jsp file
named helloworld.jsp inside it as shown below:
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolve
r">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
41
8. Your web.xml file should have following code:
9. You have to change the portno of tomcat from 8080 to 9090 since 8080 was
already been used by AddFly 10.0. To change the portno Click on Window-
>Show View->Others-> Server-> Double Click on Tomcat Server-> Slide the
upper window towards Right->Modify Http1.1 port from 8080 to 9080-> Press
Ctrl+S
10. Right Click on SpringEJBClient-> Run As-> Run on Server and type the following
URL on your browser:
http://localhost:9080/SpringEJBClient/hello?name=Benson
42
Note: In above output, you see the “Hello World !” message, which is returned
from method sayHello( ) of HelloWorldBean class belonging to MyEJBApp
project. The method is called from HelloWorldController class.
Reference:
1. http://theopentutorials.com/examples/java-ee/ejb3/how-to-create-a-simple-ejb3-
project-in-eclipse-jboss-7-1/
43
Java Messaging Service(JMS)
Java Messaging Service (JMS) is a standard messaging API used to send and receive
messages.
JMS Message Structure
Each JMS message is composed of:
JMS can be sent with several message body formats. Two common formats
are TextMessage and BytesMessage.
Header
44
The table below lists the JMS message header fields, indicates how their values are set
and describes the content of each header field.
Can
be DeliveryMode.NON_PERSISTENT or Deliv
send or publish
JMSDeliveryMode eryMode.PERSISTENT ; only persistent
method
messages guarantee delivery in case of a
crash of the brokers that transport it.
send or publish
JMSTimestamp Returns a long indicating the time of sending.
method
45
Header Field Set By Description
Properties
You can create and set properties for JMS messages if you need values in addition to
those provided by the header fields. Properties are optional and stored as standard
Java name/value pairs. Property fields are most often used for message selection and
filtering.
Body
The message body contains the main information that is being exchanged by the JMS
message. The JMS API defines five message body formats, also called message types,
46
which allow you to send and receive data in a number of forms. JMS specifies only the
interface and does not specify the implementation. This approach allows for vendor-
specific implementation and transportation of messages while using a common
interface.
At the consuming end, a message arrives as a generic Message object and must be
cast to the appropriate message type. You can use one or more getter methods to
extract the message contents. The following code fragment uses
the getText() method:
Message m = consumer.receive();
if (m instanceof TextMessage) {
47
TextMessage message = (TextMessage) m;
System.out.println("Reading message: " + message.getText());
} else {
// Handle error
}
JMS Classes
Some of the primary and important JMS classes supported by Spring are:
ConnectionFactory->Connection->Session->MessageProducer->send
Between the ConnectionFactory and the Send operation there are three
intermediate objects that are created and destroyed. To optimise the resource
usage and increase performance two implementations of ConnectionFactory are
provided.
48
number of transactions. SingleConnectionFactory takes a reference to a
standard ConnectionFactory that would typically come from JNDI.
http://www.codejava.net/frameworks/spring/configuring-spring-mvc-
jdbctemplate-with-jndi-data-source-in-tomcat
http://www.pretechsol.com/2013/12/spring-jmstemplate-and-
messagelistener.html#.V7rv6Ft97IU
ConnectionFactory Management
49
In below example, we have configured a connection factory which is used to create
connection. The connection factory will help tc connect to the message broker. Since
we’re using ActiveMQ as our message broker, we’ll have to configure the JMS
connection factory so that it knows how to connect to ActiveMQ.
ActiveMQConnectionFactory is the JMS connection factory that comes with ActiveMQ.
The brokerURL property tells the connection factory where the message broker is
located. The URL we are using is tcp://localhost:61616.
Next, we need to configure a destination. The destination can be either a queue or a
topic, depending on the needs of the application.
Once we have configured, a connection factory and destination, we will configure the
JmsTemplate bean.
Destination Management
After configuring ConnectionFactory, we have to configure the destination. Destination
can be either queue or topic. You can see below example to practically know how we
have configured Destination.
Transaction Management
<<see page no 48-49 above>>
50
JmsTemplate helps eliminating the repetitive JMS code. JmsTemplate also takes care
of creating a connection, obtaining a session, and the actual sending and receiving of
messages. This helps the developer to just focus on the construction of message. If any
JMS exception is thrown, it will be rethrown as unchecked exception as a subclass of
JmsException.
Let us develop a sample application using eclipse and spring.
1. Create a Java Project named JMSTemplateDemo,Convert it into maven and
make sure you have following dependencies information on pom.xml
<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>JMSTemplateDemo</groupId>
<artifactId>JMSTemplateDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.12.0</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
51
2. Create a package named producer inside src and create a Java file named
SpringJmsProducer.java inside it:
package producer;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
public class SpringJmsProducer {
private JmsTemplate jmsTemplate;
private Destination destination;
public JmsTemplate getJmsTemplate() {
return jmsTemplate;
}
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
public Destination getDestination() {
return destination;
}
public void setDestination(Destination destination) {
this.destination = destination;
}
public void sendMessage(final String msg) {
System.out.println("Producer sends " + msg);
jmsTemplate.send(destination, new MessageCreator() {
public Message createMessage(Session session) throws
JMSException {
return session.createTextMessage(msg);
}});
}
3. Create a package named consumer inside src and create a Java file named
SpringJmsConsumer.java inside it
package consumer;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.TextMessage;
import org.springframework.jms.core.JmsTemplate;
public class SpringJmsConsumer {
private JmsTemplate jmsTemplate;
private Destination destination;
public JmsTemplate getJmsTemplate() {
return jmsTemplate;
}
public void setJmsTemplate(JmsTemplate jmsTemplate) {
52
this.jmsTemplate = jmsTemplate;
}
public Destination getDestination() {
return destination;
}
4. Create a package named testpro inside src and create a Java file named
SpringJmsDemo.java
package testpro;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import consumer.SpringJmsConsumer;
import producer.SpringJmsProducer;
public class SpringJmsDemo {
public static void main(String[] args) throws URISyntaxException, Exception
{
BrokerService broker = BrokerFactory.createBroker(new URI(
"broker:(tcp://localhost:61616)"));
broker.start();
ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext(
"applicationContext.xml");
try {
SpringJmsProducer springJmsProducer = (SpringJmsProducer) context
.getBean("springJmsProducer");
springJmsProducer.sendMessage("Hi");
.getBean("springJmsConsumer");
} finally {
broker.stop();
context.close();
}
}
}
53
5. Create application context file named applicationContext.xml inside src folder
JMSGateway Support
In this example, our producer and consumer beans will extend JmsGatewaySupport to
access the JMS template. With this change, we can get rid of the private field
jmsTemplate and its setter method from both the producer and consumer classes.
54
<groupId>JMSTemplateDemo</groupId>
<artifactId>JMSTemplateDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.12.0</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. Create a package named producer inside src and create a Java file named
SpringJmsGatewayProducer.java inside it:
package producer;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import org.springframework.jms.core.MessageCreator;
import org.springframework.jms.core.support.JmsGatewaySupport;
public class SpringJmsGatewayProducer extends JmsGatewaySupport {
public void sendMessage(final String msg) {
System.out.println("Producer sends " + msg);
getJmsTemplate().send(new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(msg);
}});
}
}
55
3. Create a package named consumer inside src and create a Java file named
SpringJmsGatewayConsumer.java inside it
package consumer;
import javax.jms.JMSException;
import javax.jms.TextMessage;
import org.springframework.jms.core.support.JmsGatewaySupport;
public class SpringJmsGatewayConsumer extends JmsGatewaySupport {
public String receiveMessage() throws JMSException {
TextMessage textMessage = (TextMessage)
getJmsTemplate().receive();
return textMessage.getText();
}
}
4. Create a package named testpro inside src and create a Java file named
SpringJmsGatewayDemo.java
package testpro;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import consumer.SpringJmsGatewayConsumer;
import producer.SpringJmsGatewayProducer;
public class SpringJmsGatewayDemo {
public static void main(String[] args) throws URISyntaxException, Exception
{
BrokerService broker = BrokerFactory.createBroker(new URI(
"broker:(tcp://localhost:61616)"));
broker.start();
ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext(
"applicationContext.xml");
try {
SpringJmsGatewayProducer springJmsProducer =
(SpringJmsGatewayProducer) context
.getBean("springJmsGatewayProducer");
springJmsProducer.sendMessage("Hi");
SpringJmsGatewayConsumer springJmsConsumer =
(SpringJmsGatewayConsumer) context
.getBean("springJmsGatewayConsumer");
System.out.println("Consumer receives " +
springJmsConsumer.receiveMessage());
} finally {
broker.stop();
context.close();
}
}
}
56
5. Create application context file named applicationContext.xml inside src folder
<bean id="connectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
<bean id="messageDestination"
class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="messageQueue1" />
</bean>
<bean id="jmsTemplate"
class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="receiveTimeout" value="10000" />
</bean>
<bean id="jmsTemplateWithDefaultDestination"
class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="receiveTimeout" value="10000" />
<property name="defaultDestinationName" value="messageQueue2" />
</bean>
<bean id="springJmsGatewayProducer"
class="producer.SpringJmsGatewayProducer">
<property name="jmsTemplate"
ref="jmsTemplateWithDefaultDestination" />
</bean>
<bean id="springJmsGatewayConsumer"
class="consumer.SpringJmsGatewayConsumer">
<property name="jmsTemplate"
ref="jmsTemplateWithDefaultDestination" />
</bean>
</beans>
57
Message Driven Pojo(MDP)
Spring offers two ways to process JMS messages: the JmsTemplate for synchronously
sending and receiving messages and Message-Driven POJOs(MDP) for receiving
messages asynchronously.
Message-Driven POJOs( or MDPs) are asynchronous message listeners that are
managed by the Spring framework. They are similar to the Message-Driven Beans
provided by the Enterprise JavaBean(EJB) specification.However, MDPs are much
more powerful than MDB.
MDPs also support the request/reply messagine model and event-driven processing,
allowing us to send messages from an MDP using JMS API or the Spring JmsTemplate.
There are three types of MDPs
Those that implement the javax.jms.MessageListener Interface
Those that implement the SpringFramework SessionAwareMessageListener
interface
Those that use the Spring MessageListenerAdapter
MDP Example:
Message Driven Beans(MDB) can listen for JMS messages asynchronously and they
must be deployed in an EJB container to run. This MDB usually acts as a JMS message
listener pulling in messages from either queues or topics. But Spring facilitates us to
add the same capability to POJOs (declared in its IoC container) so that they can listen
for JMS messages without an EJB container. We called these bean as message-driven
POJOs (MDPs).
A Message Driven POJO (MDP) is a simple java object which implements the
javax.jms.MessageListener interface. MessageListener interface has one method
onMessage() which need to be implemented by MDP. When a JMS message arrives,
the onMessage() method will be called with the Message as the method argument.
Sample Application:
1. Create a Java Project named MDPDemo, Convert it into maven project and
make sure it has following pom.xml file
<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>MDPDemo</groupId>
58
<artifactId>MDPDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.12.0</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. Inside src folder, create a package named data and create a java file named
MessageObject.java inside it.
package data;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "MessageObject")
public class MessageObject implements Serializable{
@XmlElement(name = "mailId")
private String mailId;
59
@XmlElement(name = "message")
private String message;
public MessageObject(){};
public MessageObject(String mailId, String message) {
super();
this.mailId = mailId;
this.message = message;
}
public String getMailId() {
return mailId;
}
public void setMailId(String mailId) {
this.mailId = mailId;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
3. Inside src folder, create a package called consumer and create a java file named
MessageConsumerBean.java inside it:
package consumer;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
60
4. Inside src, create a package called producer and create a java file named
MessageProducerBean.java inside it.
package producer;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.Session;
import org.springframework.jms.core.MessageCreator;
import org.springframework.jms.core.support.JmsGatewaySupport;
import data.MessageObject;
5. Inside src, create a folder named testpro and create a Java file named
TestApp.java inside it
package testpro;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
import data.MessageObject;
import producer.MessageProducerBean;
public class TestApp {
public static void main(String[] args) throws URISyntaxException,
Exception {
BrokerService broker = BrokerFactory.createBroker(new URI(
"broker:(tcp://localhost:61616)"));
broker.start();
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
MessageProducerBean mp = (MessageProducerBean)
context.getBean("producer");
mp.sendMessage(new MessageObject("34", "Test Message"));
}
}
61
6. Create an XML file named applicationContext.xml inside src
7. Right Click MDPDemo-> Run As-> Java Application
MDP vs MDB
MDBs must run in an EJB container, MDPs can run anywhere even using simple
standalone main() apps.
MDPs can utilize all of Spring’s features like dependency injection, AOP support,
etc.
MDBs require you to implement methods of MessageDrivenBeans which lead to
unnecessary work and overhead.
When using MDPs, we are able to use Spring adapter classes and reduce and
simplify our code even more
class="org.springframework.web.servlet.view.InternalResourceViewResolve
r">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<websocket:message-broker application-destination-prefix="/calcApp">
<websocket:stomp-endpoint path="/add">
<websocket:sockjs/>
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/topic"/>
</websocket:message-broker>
</beans>
63
Note: i) In above code, stomp endpoint is “/add”, Message Broker App Prefix is
“/calcApp” and message queue prefix is “/topic”
ii) Even if editor shows error message, do not worry about it.
@Controller
public class MyController {
public MyController()
{
System.out.println("Demo Controller");
}
@RequestMapping("/welcome")
public ModelAndView helloWorld() {
@MessageMapping("/add" )
@SendTo("/topic/showResult")
public Result addNum(CalcInput input) throws Exception {
Thread.sleep(2000);
Result result = new Result(input.getNum1()+"+"+input.getNum2()
+"="+(input.getNum1()+input.getNum2()));
return result;
}
}
64
4. Create CalcInput.java inside controller package that is needed by MyController
as shown below:
package controller;
6. Inside WebContent folder, create a folder named resources and put there
jquery.js, stomp.js and sockjs.js
7. Inside WebContent/Web-Inf folder, create a folder named jsp and create hello.jsp
inside it:
65
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>WebSocketDemo</title>
66
alert("document loading...") ;
});*/
</script>
</head>
<body>
<div>
<h1>Calculator App Using Spring 4 WebSocket</h1>
${message}
<h1>---------------------------------------</h1>
<div>
<div>
<button id="connect" onclick="connect();">Connect</button>
<button id="disconnect" disabled="disabled"
onclick="disconnect();">Disconnect</button><br/><br/>
</div>
<div id="calculationDiv">
<label>Number One:</label><input type="text" id="num1" /><br/>
<label>Number Two:</label><input type="text" id="num2"
/><br/><br/>
<button id="sendNum" onclick="sendNum();">Send to Add</button>
<p id="calResponse"></p>
</div>
</div>
</div>
</body>
</html>
67
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-
class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>websock</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
12. Fill Values in the Text Box, Click Connect Button and then press “Send to Add”
Button.
Reference:
1. https://examples.javacodegeeks.com/enterprise-java/spring/spring-jms-example/
2. http://www.source4code.info/2014/01/jms-message-structure.html
3. http://claudihome.com/html/LR/WebHelp/Content/VuGen/
154750_c_WS_mgmt_jms_structure.htm
4. https://examples.javacodegeeks.com/enterprise-java/spring/spring-framework-
jmstemplate-example/
5. http://docs.spring.io/spring/docs/current/spring-framework-reference/html/
jms.html
6. http://half-wit4u.blogspot.com/2013/03/message-driven-pojo-using-spring-
and.html
7. https://gerrydevstory.com/2014/03/04/spring-4-websocket-stock-ticker-example/
68
8. http://www.concretepage.com/spring-4/spring-4-websocket-sockjs-stomp-tomcat-
example
69