diff --git a/spring-framework-reference/src/remoting.xml b/spring-framework-reference/src/remoting.xml
index aac4e6d7cad..5f0be3158e9 100644
--- a/spring-framework-reference/src/remoting.xml
+++ b/spring-framework-reference/src/remoting.xml
@@ -1,146 +1,179 @@
-
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
Remoting and web services using Spring
Introduction
- Spring features integration classes for remoting support using various
- technologies. The remoting support eases the development of remote-enabled
- services, implemented by your usual (Spring) POJOs. Currently, Spring supports
- four remoting technologies:
-
-
- Remote Method Invocation (RMI). Through the use
- of the RmiProxyFactoryBean and the
- RmiServiceExporter Spring supports both traditional
- RMI (with java.rmi.Remote interfaces and
- java.rmi.RemoteException) and
- transparent remoting via RMI invokers (with any Java interface).
-
-
- Spring's HTTP invoker. Spring provides a special
- remoting strategy which allows for Java serialization via HTTP,
- supporting any Java interface (just like the RMI invoker). The corresponding
- support classes are HttpInvokerProxyFactoryBean and
- HttpInvokerServiceExporter.
-
-
- Hessian. By using Spring's
- HessianProxyFactoryBean and the
- HessianServiceExporter you can transparently
- expose your services using the lightweight binary HTTP-based protocol
- provided by Caucho.
-
-
- Burlap. Burlap is Caucho's XML-based
- alternative to Hessian. Spring provides support classes such
- as BurlapProxyFactoryBean and
- BurlapServiceExporter.
-
-
- JAX-RPC. Spring provides remoting support
- for web services via JAX-RPC (J2EE 1.4's web service API).
-
-
- JAX-WS. Spring provides remoting support
- for web services via JAX-WS (the successor of JAX-RPC, as introduced
- in Java EE 5 and Java 6).
-
-
- JMS. Remoting using JMS as the underlying protocol
- is supported via the JmsInvokerServiceExporter and
- JmsInvokerProxyFactoryBean classes.
-
-
- While discussing the remoting capabilities of Spring, we'll use the following domain
- model and corresponding services:
+
+ Spring features integration classes for remoting support using
+ various technologies. The remoting support eases the development of
+ remote-enabled services, implemented by your usual (Spring) POJOs.
+ Currently, Spring supports four remoting technologies:
+
+ Remote Method Invocation (RMI). Through
+ the use of the RmiProxyFactoryBean and the
+ RmiServiceExporter Spring supports both
+ traditional RMI (with java.rmi.Remote
+ interfaces and
+ java.rmi.RemoteException) and
+ transparent remoting via RMI invokers (with any Java
+ interface).
+
+
+
+ Spring's HTTP invoker. Spring provides a
+ special remoting strategy which allows for Java serialization via
+ HTTP, supporting any Java interface (just like the RMI invoker). The
+ corresponding support classes are
+ HttpInvokerProxyFactoryBean and
+ HttpInvokerServiceExporter.
+
+
+
+ Hessian. By using Spring's
+ HessianProxyFactoryBean and the
+ HessianServiceExporter you can transparently
+ expose your services using the lightweight binary HTTP-based
+ protocol provided by Caucho.
+
+
+
+ Burlap. Burlap is Caucho's XML-based
+ alternative to Hessian. Spring provides support classes such as
+ BurlapProxyFactoryBean and
+ BurlapServiceExporter.
+
+
+
+ JAX-RPC. Spring provides remoting support
+ for web services via JAX-RPC (J2EE 1.4's web service API).
+
+
+
+ JAX-WS. Spring provides remoting support
+ for web services via JAX-WS (the successor of JAX-RPC, as introduced
+ in Java EE 5 and Java 6).
+
+
+
+ JMS. Remoting using JMS as the underlying
+ protocol is supported via the
+ JmsInvokerServiceExporter and
+ JmsInvokerProxyFactoryBean classes.
+
+
+
+ While discussing the remoting capabilities of Spring, we'll use the
+ following domain model and corresponding services:
+
+
getAccounts(String name);
}]]>
+
getAccounts(String name) throws RemoteException;
}]]>
- // the implementation doing nothing at the moment// the implementation doing nothing at the moment
public class AccountServiceImpl implements AccountService {
public void insertAccount(Account acc) {
- ]]>// do something...// do something...
}
- public List getAccounts(String name) {
- ]]>// do something...// do something...
}
-}]]>
- We will start exposing the service to a remote client by using RMI and
- talk a bit about the drawbacks of using RMI. We'll then continue to show
- an example using Hessian as the protocol.
+}
+
+ We will start exposing the service to a remote client by using RMI
+ and talk a bit about the drawbacks of using RMI. We'll then continue to
+ show an example using Hessian as the protocol.
Exposing services using RMI
- Using Spring's support for RMI, you can transparently expose your services through
- the RMI infrastructure. After having this set up, you basically have a configuration
- similar to remote EJBs, except for the fact that there is no standard support for
- security context propagation or remote transaction propagation. Spring does provide
- hooks for such additional invocation context when using the RMI invoker, so you can
- for example plug in security frameworks or custom security credentials here.
+
+ Using Spring's support for RMI, you can transparently expose your
+ services through the RMI infrastructure. After having this set up, you
+ basically have a configuration similar to remote EJBs, except for the fact
+ that there is no standard support for security context propagation or
+ remote transaction propagation. Spring does provide hooks for such
+ additional invocation context when using the RMI invoker, so you can for
+ example plug in security frameworks or custom security credentials
+ here.
- Exporting the service using the RmiServiceExporter
- Using the RmiServiceExporter, we can expose the interface
- of our AccountService object as RMI object. The interface can be accessed by using
- RmiProxyFactoryBean, or via plain RMI in case of a traditional
- RMI service. The RmiServiceExporter explicitly supports the
- exposing of any non-RMI services via RMI invokers.
-
- Of course, we first have to set up our service in the Spring container:
-
- ]]><!-- any additional properties, maybe a DAO? -->]]>
- Next we'll have to expose our service using the RmiServiceExporter:
-
- ]]><!-- does not necessarily have to be the same name as the bean to be exported -->
-
-
- ]]><!-- defaults to 1099 -->
-]]>
- As you can see, we're overriding the port for the RMI registry. Often,
- your application server also maintains an RMI registry and it is wise
- to not interfere with that one. Furthermore, the service name is used to bind the
- service under. So right now, the service will be bound at
- 'rmi://HOST:1199/AccountService'. We'll use the URL later on to
- link in the service at the client side.
+ Exporting the service using the
+ RmiServiceExporter
+
+ Using the RmiServiceExporter, we can expose
+ the interface of our AccountService object as RMI object. The interface
+ can be accessed by using RmiProxyFactoryBean, or
+ via plain RMI in case of a traditional RMI service. The
+ RmiServiceExporter explicitly supports the
+ exposing of any non-RMI services via RMI invokers.
+
+ Of course, we first have to set up our service in the Spring
+ container:
+
+ <bean id="accountService" class="example.AccountServiceImpl">
+ <!-- any additional properties, maybe a DAO? -->
+</bean>
+
+ Next we'll have to expose our service using the
+ RmiServiceExporter:
+
+ <bean class="org.springframework.remoting.rmi.RmiServiceExporter">
+ <!-- does not necessarily have to be the same name as the bean to be exported -->
+ <property name="serviceName" value="AccountService"/>
+ <property name="service" ref="accountService"/>
+ <property name="serviceInterface" value="example.AccountService"/>
+ <!-- defaults to 1099 -->
+ <property name="registryPort" value="1199"/>
+</bean>
+
+ As you can see, we're overriding the port for the RMI registry.
+ Often, your application server also maintains an RMI registry and it is
+ wise to not interfere with that one. Furthermore, the service name is
+ used to bind the service under. So right now, the service will be bound
+ at 'rmi://HOST:1199/AccountService'. We'll use the
+ URL later on to link in the service at the client side.
+
- The servicePort property has been omitted (it defaults to 0).
- This means that an anonymous port will be used to communicate with the service.
+ The servicePort property has been omitted (it
+ defaults to 0). This means that an anonymous port will be used to
+ communicate with the service.
Linking in the service at the client
- Our client is a simple object using the AccountService
- to manage accounts:
+
+ Our client is a simple object using the
+ AccountService to manage accounts:
+
- To link in the service on the client, we'll create a separate Spring container,
- containing the simple object and the service linking configuration bits:
-
+
+ To link in the service on the client, we'll create a separate
+ Spring container, containing the simple object and the service linking
+ configuration bits:
+
+
@@ -159,27 +198,34 @@ public class AccountServiceImpl implements AccountService {
]]>
- That's all we need to do to support the remote account service on the client.
- Spring will transparently create an invoker and remotely enable the account
- service through the RmiServiceExporter. At the client
- we're linking it in using the RmiProxyFactoryBean.
+
+ That's all we need to do to support the remote account service on
+ the client. Spring will transparently create an invoker and remotely
+ enable the account service through the
+ RmiServiceExporter. At the client we're linking
+ it in using the RmiProxyFactoryBean.
Using Hessian or Burlap to remotely call services via HTTP
- Hessian offers a binary HTTP-based remoting protocol. It is developed by
- Caucho and more information about Hessian itself can be found at
- .
+
+ Hessian offers a binary HTTP-based remoting protocol. It is
+ developed by Caucho and more information about Hessian itself can be found
+ at .
- Wiring up the DispatcherServlet for Hessian and co.
- Hessian communicates via HTTP and does so using a custom servlet.
- Using Spring's DispatcherServlet principles, as known
- from Spring Web MVC usage, you can easily wire up such a servlet exposing
- your services. First we'll have to create a new servlet in your application
- (this an excerpt from 'web.xml'):
-
+ Wiring up the DispatcherServlet for
+ Hessian and co.
+
+ Hessian communicates via HTTP and does so using a custom servlet.
+ Using Spring's DispatcherServlet principles, as
+ known from Spring Web MVC usage, you can easily wire up such a servlet
+ exposing your services. First we'll have to create a new servlet in your
+ application (this an excerpt from
+ 'web.xml'):
+
+
remoting
org.springframework.web.servlet.DispatcherServlet
1
@@ -189,47 +235,66 @@ public class AccountServiceImpl implements AccountService {
remoting
/remoting/*
]]>
- You're probably familiar with Spring's DispatcherServlet
- principles and if so, you know that now you'll have to create a Spring container
- configuration resource named 'remoting-servlet.xml' (after
- the name of your servlet) in the 'WEB-INF'
- directory. The application context will be used in the next section.
+
+ You're probably familiar with Spring's
+ DispatcherServlet principles and if so, you know
+ that now you'll have to create a Spring container configuration resource
+ named 'remoting-servlet.xml' (after the name of
+ your servlet) in the 'WEB-INF'
+ directory. The application context will be used in the next
+ section.
+
Alternatively, consider the use of Spring's simpler
- HttpRequestHandlerServlet.
- This allows you to embed the remote exporter definitions in your root application
- context (by default in 'WEB-INF/applicationContext.xml'),
+ HttpRequestHandlerServlet. This allows you to
+ embed the remote exporter definitions in your root application context
+ (by default in 'WEB-INF/applicationContext.xml'),
with individual servlet definitions pointing to specific exporter beans.
- Each servlet name needs to match the bean name of its target exporter in this case.
+ Each servlet name needs to match the bean name of its target exporter in
+ this case.
- Exposing your beans by using the HessianServiceExporter
- In the newly created application context called remoting-servlet.xml,
- we'll create a HessianServiceExporter exporting your services:
-
- ]]><!-- any additional properties, maybe a DAO? -->
+ Exposing your beans by using the
+ HessianServiceExporter
+
+ In the newly created application context called
+ remoting-servlet.xml, we'll create a
+ HessianServiceExporter exporting your
+ services:
+
+ <bean id="accountService" class="example.AccountServiceImpl">
+ <!-- any additional properties, maybe a DAO? -->
+</bean>
+
+<bean name="/AccountService" class="org.springframework.remoting.caucho.HessianServiceExporter">
+ <property name="service" ref="accountService"/>
+ <property name="serviceInterface" value="example.AccountService"/>
+</bean>
+
+ Now we're ready to link in the service at the client. No explicit
+ handler mapping is specified, mapping request URLs onto services, so
+ BeanNameUrlHandlerMapping will be used: Hence,
+ the service will be exported at the URL indicated through its bean name
+ within the containing DispatcherServlet's mapping
+ (as defined above):
+ 'http://HOST:8080/remoting/AccountService'.
+
+ Alternatively, create a
+ HessianServiceExporter in your root application
+ context (e.g. in
+ 'WEB-INF/applicationContext.xml'):
-
-
-
-]]>
- Now we're ready to link in the service at the client. No explicit handler mapping
- is specified, mapping request URLs onto services, so BeanNameUrlHandlerMapping
- will be used: Hence, the service will be exported at the URL indicated through
- its bean name within the containing DispatcherServlet's
- mapping (as defined above): 'http://HOST:8080/remoting/AccountService'.
-
- Alternatively, create a HessianServiceExporter in your
- root application context (e.g. in 'WEB-INF/applicationContext.xml'):
]]>
- In the latter case, define a corresponding servlet for this exporter
- in 'web.xml', with the same end result: The exporter
- getting mapped to the request path /remoting/AccountService.
- Note that the servlet name needs to match the bean name of the target exporter.
+
+ In the latter case, define a corresponding servlet for this
+ exporter in 'web.xml', with the same end result:
+ The exporter getting mapped to the request path
+ /remoting/AccountService. Note that the servlet name
+ needs to match the bean name of the target exporter.
+
accountExporter
org.springframework.web.context.support.HttpRequestHandlerServlet
@@ -243,12 +308,15 @@ public class AccountServiceImpl implements AccountService {
Linking in the service on the client
- Using the we can link in the service
- at the client. The same principles apply as with the RMI example. We'll create
- a separate bean factory or application context and mention the following beans
- where the SimpleObject is using the
+
+ Using the HessianProxyFactoryBean we can
+ link in the service at the client. The same principles apply as with the
+ RMI example. We'll create a separate bean factory or application context
+ and mention the following beans where the
+ SimpleObject is using the
AccountService to manage accounts:
-
+
+
@@ -256,24 +324,31 @@ public class AccountServiceImpl implements AccountService {
]]>
-
+
Using Burlap
- We won't discuss Burlap, the XML-based equivalent of Hessian, in detail here,
- since it is configured and set up in exactly the same way as the Hessian
- variant explained above. Just replace the word Hessian
- with Burlap and you're all set to go.
+
+ We won't discuss Burlap, the XML-based equivalent of Hessian, in
+ detail here, since it is configured and set up in exactly the same way
+ as the Hessian variant explained above. Just replace the word
+ Hessian with Burlap and you're all
+ set to go.
- Applying HTTP basic authentication to a service exposed through Hessian or Burlap
- One of the advantages of Hessian and Burlap is that we can easily apply HTTP basic
- authentication, because both protocols are HTTP-based. Your normal HTTP server security
- mechanism can easily be applied through using the web.xml security
- features, for example. Usually, you don't use per-user security credentials here, but
- rather shared credentials defined at the Hessian/BurlapProxyFactoryBean level
- (similar to a JDBC DataSource).
+ Applying HTTP basic authentication to a service exposed through
+ Hessian or Burlap
+
+ One of the advantages of Hessian and Burlap is that we can easily
+ apply HTTP basic authentication, because both protocols are HTTP-based.
+ Your normal HTTP server security mechanism can easily be applied through
+ using the web.xml security features, for example.
+ Usually, you don't use per-user security credentials here, but rather
+ shared credentials defined at the
+ Hessian/BurlapProxyFactoryBean level (similar to a
+ JDBC DataSource).
+
@@ -282,59 +357,78 @@ public class AccountServiceImpl implements AccountService {
class="org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor">
]]>
- This an example where we explicitly mention the BeanNameUrlHandlerMapping
- and set an interceptor allowing only administrators and operators to call
- the beans mentioned in this application context.
+
+ This an example where we explicitly mention the
+ BeanNameUrlHandlerMapping and set an interceptor
+ allowing only administrators and operators to call the beans mentioned
+ in this application context.
+
Of course, this example doesn't show a flexible kind of security
- infrastructure. For more options as far as security is concerned,
- have a look at the Acegi Security System for Spring, to be found at
- .
+ infrastructure. For more options as far as security is concerned, have
+ a look at the Acegi Security System for Spring, to be found at .
-
-
- Exposing services using HTTP invokers
- As opposed to Burlap and Hessian, which are both lightweight protocols using their
- own slim serialization mechanisms, Spring Http invokers use the standard
- Java serialization mechanism to expose services through HTTP. This has a huge
- advantage if your arguments and return types are complex types that cannot be
- serialized using the serialization mechanisms Hessian and Burlap use (refer to the
- next section for more considerations when choosing a remoting technology).
- Under the hood, Spring uses either the standard facilities provided by J2SE to
- perform HTTP calls or Commons HttpClient. Use the latter if you need more advanced
- and easy-to-use functionality. Refer to
- jakarta.apache.org/commons/httpclient
- for more info.
-
- Exposing the service object
- Setting up the HTTP invoker infrastructure for a service objects much resembles
- the way you would do using Hessian or Burlap. Just as Hessian support provides
- the HessianServiceExporter, Spring's HttpInvoker support provides
- the org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter.
-
- To expose the AccountService (mentioned above) within a
- Spring Web MVC DispatcherServlet, the following configuration
- needs to be in place in the dispatcher's application context:
-
+
+ Exposing services using HTTP invokers
+
+ As opposed to Burlap and Hessian, which are both lightweight
+ protocols using their own slim serialization mechanisms, Spring Http
+ invokers use the standard Java serialization mechanism to expose services
+ through HTTP. This has a huge advantage if your arguments and return types
+ are complex types that cannot be serialized using the serialization
+ mechanisms Hessian and Burlap use (refer to the next section for more
+ considerations when choosing a remoting technology).
+
+ Under the hood, Spring uses either the standard facilities provided
+ by J2SE to perform HTTP calls or Commons
+ HttpClient. Use the latter if you need more
+ advanced and easy-to-use functionality. Refer to jakarta.apache.org/commons/httpclient
+ for more info.
+
+
+ Exposing the service object
+
+ Setting up the HTTP invoker infrastructure for a service objects
+ much resembles the way you would do using Hessian or Burlap. Just as
+ Hessian support provides the
+ HessianServiceExporter, Spring's HttpInvoker
+ support provides the
+ org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter.
+
+ To expose the AccountService (mentioned above)
+ within a Spring Web MVC DispatcherServlet, the
+ following configuration needs to be in place in the dispatcher's
+ application context:
+
+
]]>
+
Such an exporter definition will be exposed through the
DispatcherServlet's standard mapping facilities,
as explained in the section on Hessian.
- Alternatively, create an HttpInvokerServiceExporter in your
- root application context (e.g. in 'WEB-INF/applicationContext.xml'):
+
+ Alternatively, create an
+ HttpInvokerServiceExporter in your root
+ application context (e.g. in
+ 'WEB-INF/applicationContext.xml'):
+
]]>
+
In addition, define a corresponding servlet for this exporter in
'web.xml', with the servlet name matching the bean
name of the target exporter:
+
accountExporter
org.springframework.web.context.support.HttpRequestHandlerServlet
@@ -344,24 +438,51 @@ public class AccountServiceImpl implements AccountService {
accountExporter
/remoting/AccountService
]]>
+
+ f you are running outside of a servlet container and are using
+ Sun's Java 6, then you can use the built-in HTTP server implementation.
+ You can configure the SimpleHttpServerFactoryBean together with a
+ SimpleHttpInvokerServiceExporter as is shown in this example:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]]>
Linking in the service at the client
- Again, linking in the service from the client much resembles the way you would
- do it when using Hessian or Burlap. Using a proxy, Spring will be able to
- translate your calls to HTTP POST requests to the URL pointing to the exported
- service.
-
+
+ Again, linking in the service from the client much resembles the
+ way you would do it when using Hessian or Burlap. Using a proxy, Spring
+ will be able to translate your calls to HTTP POST requests to the URL
+ pointing to the exported service.
+
+
]]>
- As mentioned before, you can choose what HTTP client you want to use.
- By default, the HttpInvokerProxy uses the J2SE HTTP functionality, but
- you can also use the Commons HttpClient by setting the
+
+ As mentioned before, you can choose what HTTP client you want to
+ use. By default, the HttpInvokerProxy uses the
+ J2SE HTTP functionality, but you can also use the Commons
+ HttpClient by setting the
httpInvokerRequestExecutor property:
-
+
+
]]>
@@ -370,43 +491,67 @@ public class AccountServiceImpl implements AccountService {
Web services
- Spring provides full support for standard Java web services APIs:
+
+ Spring provides full support for standard Java web services
+ APIs:
+
- Exposing web services using JAX-RPC
- Accessing web services using JAX-RPC
- Exposing web services using JAX-WS
- Accessing web services using JAX-WS
+
+ Exposing web services using JAX-RPC
+
+
+
+ Accessing web services using JAX-RPC
+
+
+
+ Exposing web services using JAX-WS
+
+
+
+ Accessing web services using JAX-WS
+
+
Why two standard Java web services APIs?
- JAX-RPC 1.1 is the standard web service API in J2EE 1.4.
- As its name indicates, it focuses on on RPC bindings, which became
- less and less popular in the past couple of years. As a consequence,
- it has been superseded by JAX-WS 2.0 in Java EE 5, being more flexible
- in terms of bindings but also being heavily annotation-based. JAX-WS 2.1
- is also included in Java 6 (or more specifically, in Sun's JDK 1.6.0_04
- and above; previous Sun JDK 1.6.0 releases included JAX-WS 2.0),
- integrated with the JDK's built-in HTTP server.
- Spring can work with both standard Java web services APIs.
- The choice is effectively dependent on the runtime platform:
- On JDK 1.4 / J2EE 1.4, the only option is JAX-RPC. On Java EE 5 / Java 6,
- the obvious choice is JAX-WS. On J2EE 1.4 environments that run on Java 5,
- you might have the option to plug in a JAX-WS provider; check your J2EE
- server's documentation.
+
+ JAX-RPC 1.1 is the standard web service API in J2EE 1.4. As its
+ name indicates, it focuses on on RPC bindings, which became less and
+ less popular in the past couple of years. As a consequence, it has been
+ superseded by JAX-WS 2.0 in Java EE 5, being more flexible in terms of
+ bindings but also being heavily annotation-based. JAX-WS 2.1 is also
+ included in Java 6 (or more specifically, in Sun's JDK 1.6.0_04 and
+ above; previous Sun JDK 1.6.0 releases included JAX-WS 2.0), integrated
+ with the JDK's built-in HTTP server.
+
+ Spring can work with both standard Java web services APIs. On Java
+ EE 5 / Java 6, the obvious choice is JAX-WS. On J2EE 1.4 environments
+ that run on Java 5, you might have the option to plug in a JAX-WS
+ provider; check your J2EE server's documentation.
- In addition to stock support for JAX-RPC and JAX-WS in Spring Core, the Spring portfolio also
- features Spring Web Services, a solution
- for contract-first, document-driven web services - highly recommended for building modern, future-proof
- web services. Last but not least, XFire also allows
- you to export Spring-managed beans as a web service, through built-in Spring support.
+
+ In addition to stock support for JAX-RPC and JAX-WS in Spring Core,
+ the Spring portfolio also features Spring Web
+ Services, a solution for contract-first, document-driven web
+ services - highly recommended for building modern, future-proof web
+ services. Last but not least, XFire also allows you to export
+ Spring-managed beans as a web service, through built-in Spring
+ support.
Exposing servlet-based web services using JAX-RPC
- Spring provides a convenience base class for JAX-RPC servlet endpoint implementations -
+
+ Spring provides a convenience base class for JAX-RPC servlet
+ endpoint implementations -
ServletEndpointSupport. To expose our
AccountService we extend Spring's
- ServletEndpointSupport class and implement our business
- logic here, usually delegating the call to the business layer.
+ ServletEndpointSupport class and implement our
+ business logic here, usually delegating the call to the business
+ layer.
+
/**
* JAX-RPC compliant RemoteAccountService implementation that simply delegates
* to the AccountService implementation in the root web application context.
@@ -420,12 +565,12 @@ public class AccountServiceImpl implements AccountService {
* In the case of Axis, this happens in "server-config.wsdd" respectively via
* deployment calls. The web service engine manages the lifecycle of instances
* of this class: A Spring application context can just be accessed here.
- */import org.springframework.remoting.jaxrpc.ServletEndpointSupport;
public class AccountServiceEndpoint extends ServletEndpointSupport implements RemoteAccountService {
private AccountService biz;
-
+
protected void onInit() {
this.biz = (AccountService) getWebApplicationContext().getBean("accountService");
}
@@ -437,27 +582,33 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re
public Account[] getAccounts(String name) throws RemoteException {
return biz.getAccounts(name);
}
-}]]>
- Our AccountServletEndpoint needs to run in the same web
- application as the Spring context to allow for access to Spring's facilities. In case of
- Axis, copy the AxisServlet definition into your
+}
+
+ Our AccountServletEndpoint needs to run in
+ the same web application as the Spring context to allow for access to
+ Spring's facilities. In case of Axis, copy the
+ AxisServlet definition into your
'web.xml', and set up the endpoint in
- 'server-config.wsdd' (or use the deploy tool). See the sample
- application JPetStore where the OrderService is exposed as
- a web service using Axis.
+ 'server-config.wsdd' (or use the deploy tool). See
+ the sample application JPetStore where the
+ OrderService is exposed as a web service
+ using Axis.
Accessing web services using JAX-RPC
- Spring provides two factory beans to create JAX-RPC web service proxies,
- namely LocalJaxRpcServiceFactoryBean and
- JaxRpcPortProxyFactoryBean. The former can only return a JAX-RPC
- service class for us to work with. The latter is the full-fledged version that can return
- a proxy that implements our business service interface. In this example we use the latter
- to create a proxy for the AccountService endpoint we exposed
- in the previous section. You will see that Spring has great support for web services
- requiring little coding efforts - most of the setup is done in the Spring configuration
- file as usual:
+
+ Spring provides two factory beans to create JAX-RPC web service
+ proxies, namely LocalJaxRpcServiceFactoryBean and
+ JaxRpcPortProxyFactoryBean. The former can only
+ return a JAX-RPC service class for us to work with. The latter is the
+ full-fledged version that can return a proxy that implements our
+ business service interface. In this example we use the latter to create
+ a proxy for the AccountService endpoint
+ we exposed in the previous section. You will see that Spring has great
+ support for web services requiring little coding efforts - most of the
+ setup is done in the Spring configuration file as usual:
+
@@ -465,21 +616,31 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re
]]>
- Where serviceInterface is our remote business interface the clients will use.
- wsdlDocumentUrl is the URL for the WSDL file. Spring needs this a startup time to create the JAX-RPC Service.
- namespaceUri corresponds to the targetNamespace in the .wsdl file.
- serviceName corresponds to the service name in the .wsdl file.
- portName corresponds to the port name in the .wsdl file.
-
- Accessing the web service is now very easy as we have a bean factory for it that will expose it
- as RemoteAccountService interface. We can wire this up in Spring:
+
+ Where serviceInterface is our remote business
+ interface the clients will use. wsdlDocumentUrl is
+ the URL for the WSDL file. Spring needs this a startup time to create
+ the JAX-RPC Service. namespaceUri corresponds to the
+ targetNamespace in the .wsdl file. serviceName
+ corresponds to the service name in the .wsdl file.
+ portName corresponds to the port name in the .wsdl
+ file.
+
+ Accessing the web service is now very easy as we have a bean
+ factory for it that will expose it as
+ RemoteAccountService interface. We can wire this up
+ in Spring:
+
...
]]>
+
From the client code we can access the web service just as if it
- was a normal class, except that it throws RemoteException.
-RemoteException.
+
+ public class AccountClientImpl {
private RemoteAccountService service;
@@ -492,22 +653,29 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re
service.insertAccount(...);
}
catch (RemoteException ex) {
- ]]>// ouch// ouch
}
}
}
-]]>
- We can get rid of the checked RemoteException since
- Spring supports automatic conversion to its corresponding unchecked
- RemoteException. This requires that we provide a non-RMI
- interface also. Our configuration is now:
+
+
+ We can get rid of the checked
+ RemoteException since Spring supports
+ automatic conversion to its corresponding unchecked
+ RemoteException. This requires that we
+ provide a non-RMI interface also. Our configuration is now:
+
+ ...
]]>
- Where serviceInterface is changed to our non RMI interface. Our RMI
- interface is now defined using the property portInterface. Our client
- code can now avoid handling java.rmi.RemoteException:
+
+ Where serviceInterface is changed to our non
+ RMI interface. Our RMI interface is now defined using the property
+ portInterface. Our client code can now avoid handling
+ java.rmi.RemoteException:
+
- Note that you can also drop the "portInterface" part and specify a plain
- business interface as "serviceInterface". In this case,
- JaxRpcPortProxyFactoryBean will automatically switch
- to the JAX-RPC "Dynamic Invocation Interface", performing dynamic invocations
- without a fixed port stub. The advantage is that you don't even need to have
- an RMI-compliant Java port interface around (e.g. in case of a non-Java target
- web service); all you need is a matching business interface. Check out
+
+ Note that you can also drop the "portInterface" part and specify a
+ plain business interface as "serviceInterface". In this case,
+ JaxRpcPortProxyFactoryBean will automatically
+ switch to the JAX-RPC "Dynamic Invocation Interface", performing dynamic
+ invocations without a fixed port stub. The advantage is that you don't
+ even need to have an RMI-compliant Java port interface around (e.g. in
+ case of a non-Java target web service); all you need is a matching
+ business interface. Check out
JaxRpcPortProxyFactoryBean's javadoc for details
on the runtime implications.
Registering JAX-RPC Bean Mappings
- To transfer complex objects over the wire such as Account we must
- register bean mappings on the client side.
+
+ To transfer complex objects over the wire such as
+ Account we must register bean mappings on the
+ client side.
+
- On the server side using Axis registering bean mappings is usually done in
- the 'server-config.wsdd' file.
+ On the server side using Axis registering bean mappings is
+ usually done in the 'server-config.wsdd'
+ file.
- We will use Axis to register bean mappings on the client side. To do this we need to
- register the bean mappings programmatically:
+
+ We will use Axis to register bean mappings on the client side. To
+ do this we need to register the bean mappings programmatically:
+
-
+
Registering your own JAX-RPC Handler
+
In this section we will register our own
- javax.rpc.xml.handler.Handler to the web service proxy
- where we can do custom code before the SOAP message is sent over the wire.
- The Handler is a callback interface. There is a convenience
- base class provided in jaxrpc.jar, namely
- javax.rpc.xml.handler.GenericHandler that we will extend:
+ javax.rpc.xml.handler.Handler to the web
+ service proxy where we can do custom code before the SOAP message is
+ sent over the wire. The Handler is a
+ callback interface. There is a convenience base class provided in
+ jaxrpc.jar, namely
+ javax.rpc.xml.handler.GenericHandler that we will
+ extend:
+
- What we need to do now is to register our AccountHandler to JAX-RPC Service so it would
- invoke handleRequest(..) before the message is sent over the wire.
- Spring has at this time of writing no declarative support for registering handlers, so we must
- use the programmatic approach. However Spring has made it very easy for us to do this as we can
- override the postProcessJaxRpcService(..) method that is designed for
- this:
+
+ What we need to do now is to register our AccountHandler to
+ JAX-RPC Service so it would invoke
+ handleRequest(..) before the message is sent
+ over the wire. Spring has at this time of writing no declarative support
+ for registering handlers, so we must use the programmatic approach.
+ However Spring has made it very easy for us to do this as we can
+ override the postProcessJaxRpcService(..)
+ method that is designed for this:
+
- The last thing we must remember to do is to change the Spring configuration to use our
- factory bean:
-
+
+ The last thing we must remember to do is to change the Spring
+ configuration to use our factory bean:
+
+
...
]]>
-
+
Exposing servlet-based web services using JAX-WS
- Spring provides a convenient base class for JAX-WS servlet endpoint implementations -
+
+ Spring provides a convenient base class for JAX-WS servlet
+ endpoint implementations -
SpringBeanAutowiringSupport. To expose our
AccountService we extend Spring's
- SpringBeanAutowiringSupport class and implement our business
- logic here, usually delegating the call to the business layer.
- We'll simply use Spring 2.5's @Autowired
- annotation for expressing such dependencies on Spring-managed beans.
+ SpringBeanAutowiringSupport class and implement
+ our business logic here, usually delegating the call to the business
+ layer. We'll simply use Spring 2.5's @Autowired
+ annotation for expressing such dependencies on Spring-managed
+ beans.
+
/**
* JAX-WS compliant AccountService implementation that simply delegates
* to the AccountService implementation in the root web application context.
@@ -634,7 +824,8 @@ public class AccountServiceEndpoint extends ServletEndpointSupport implements Re
*
* The web service engine manages the lifecycle of instances of this class.
* Spring bean references will just be wired in here.
- */
+import org.springframework.web.context.support.SpringBeanAutowiringSupport;
@WebService(serviceName="AccountService")
public class AccountServiceEndpoint extends SpringBeanAutowiringSupport {
@@ -651,29 +842,36 @@ public class AccountServiceEndpoint extends SpringBeanAutowiringSupport {
public Account[] getAccounts(String name) {
return biz.getAccounts(name);
}
-}]]>
- Our AccountServletEndpoint needs to run in the same web
- application as the Spring context to allow for access to Spring's facilities. This is
- the case by default in Java EE 5 environments, using the standard contract for JAX-WS
- servlet endpoint deployment. See Java EE 5 web service tutorials for details.
+}
+
+ Our AccountServletEndpoint needs to run in
+ the same web application as the Spring context to allow for access to
+ Spring's facilities. This is the case by default in Java EE 5
+ environments, using the standard contract for JAX-WS servlet endpoint
+ deployment. See Java EE 5 web service tutorials for details.
Exporting standalone web services using JAX-WS
- The built-in JAX-WS provider that comes with Sun's JDK 1.6 supports exposure
- of web services using the built-in HTTP server that's included in JDK 1.6 as well.
- Spring's SimpleJaxWsServiceExporter detects all
- @WebService annotated beans in the Spring application context,
- exporting them through the default JAX-WS server (the JDK 1.6 HTTP server).
- In this scenario, the endpoint instances are defined and managed as Spring beans
- themselves; they will be registered with the JAX-WS engine but their lifecycle
- will be up to the Spring application context. This means that Spring functionality
- like explicit dependency injection may be applied to the endpoint instances.
- Of course, annotation-driven injection through @Autowired
- will work as well.
-
+
+ The built-in JAX-WS provider that comes with Sun's JDK 1.6
+ supports exposure of web services using the built-in HTTP server that's
+ included in JDK 1.6 as well. Spring's
+ SimpleJaxWsServiceExporter detects all
+ @WebService annotated beans in the Spring application
+ context, exporting them through the default JAX-WS server (the JDK 1.6
+ HTTP server).
+
+ In this scenario, the endpoint instances are defined and managed
+ as Spring beans themselves; they will be registered with the JAX-WS
+ engine but their lifecycle will be up to the Spring application context.
+ This means that Spring functionality like explicit dependency injection
+ may be applied to the endpoint instances. Of course, annotation-driven
+ injection through @Autowired will work as
+ well.
+
-
+
@@ -681,12 +879,14 @@ public class AccountServiceEndpoint extends SpringBeanAutowiringSupport {
...]]>
+
The AccountServiceEndpoint may derive from
Spring's SpringBeanAutowiringSupport but doesn't
- have to since the endpoint is a fully Spring-managed bean here.
- This means that the endpoint implementation may look like as follows,
- without any superclass declared - and Spring's @Autowired
- configuration annotation still being honored:
+ have to since the endpoint is a fully Spring-managed bean here. This
+ means that the endpoint implementation may look like as follows, without
+ any superclass declared - and Spring's @Autowired
+ configuration annotation still being honored:
+
getAccounts(String name) {
return biz.getAccounts(name);
}
}]]>
- Exporting web services using the JAX-WS RI's Spring support
- Sun's JAX-WS RI, developed as part of the GlassFish project, ships Spring support
- as part of its JAX-WS Commons project. This allows for defining JAX-WS endpoints as
- Spring-managed beans, similar to the standalone mode discussed in the previous section
- - but this time in a Servlet environment. Note that this is not portable
- in a Java EE 5 environment; it is mainly intended for non-EE environments such as Tomcat,
- embedding the JAX-WS RI as part of the web application.
- The difference to the standard style of exporting servlet-based endpoints is
- that the lifecycle of the endpoint instances themselves will be managed by Spring here,
- and that there will be only one JAX-WS servlet defined in web.xml.
- With the standard Java EE 5 style (as illustrated above), you'll have one servlet
- definition per service endpoint, with each endpoint typically delegating to Spring
- beans (through the use of @Autowired, as shown above).
- Check out
- https://jax-ws-commons.dev.java.net/spring/
+ Exporting web services using the JAX-WS RI's Spring
+ support
+
+ Sun's JAX-WS RI, developed as part of the GlassFish project, ships
+ Spring support as part of its JAX-WS Commons project. This allows for
+ defining JAX-WS endpoints as Spring-managed beans, similar to the
+ standalone mode discussed in the previous section - but this time in a
+ Servlet environment. Note that this is not portable in a Java
+ EE 5 environment; it is mainly intended for non-EE environments such as
+ Tomcat, embedding the JAX-WS RI as part of the web
+ application.
+
+ The difference to the standard style of exporting servlet-based
+ endpoints is that the lifecycle of the endpoint instances themselves
+ will be managed by Spring here, and that there will be only one JAX-WS
+ servlet defined in web.xml. With the standard Java EE
+ 5 style (as illustrated above), you'll have one servlet definition per
+ service endpoint, with each endpoint typically delegating to Spring
+ beans (through the use of @Autowired, as shown
+ above).
+
+ Check out https://jax-ws-commons.dev.java.net/spring/
for the details on setup and usage style.
Accessing web services using JAX-WS
- Analogous to the JAX-RPC support, Spring provides two factory beans
- to create JAX-WS web service proxies, namely LocalJaxWsServiceFactoryBean and
- JaxWsPortProxyFactoryBean. The former can only return a JAX-WS
- service class for us to work with. The latter is the full-fledged version that can return
- a proxy that implements our business service interface. In this example we use the latter
- to create a proxy for the AccountService endpoint (again):
-
+
+ Analogous to the JAX-RPC support, Spring provides two factory
+ beans to create JAX-WS web service proxies, namely
+ LocalJaxWsServiceFactoryBean and
+ JaxWsPortProxyFactoryBean. The former can only
+ return a JAX-WS service class for us to work with. The latter is the
+ full-fledged version that can return a proxy that implements our
+ business service interface. In this example we use the latter to create
+ a proxy for the AccountService endpoint
+ (again):
+
-
-
+
+
-
+
]]>
- Where serviceInterface is our business interface the clients will use.
- wsdlDocumentUrl is the URL for the WSDL file. Spring needs this a startup time to create the JAX-WS Service.
- namespaceUri corresponds to the targetNamespace in the .wsdl file.
- serviceName corresponds to the service name in the .wsdl file.
- portName corresponds to the port name in the .wsdl file.
-
- Accessing the web service is now very easy as we have a bean factory for it that will expose it
- as AccountService interface. We can wire this up in Spring:
+
+ Where serviceInterface is our business
+ interface the clients will use. wsdlDocumentUrl is
+ the URL for the WSDL file. Spring needs this a startup time to create
+ the JAX-WS Service. namespaceUri corresponds to the
+ targetNamespace in the .wsdl file. serviceName
+ corresponds to the service name in the .wsdl file.
+ portName corresponds to the port name in the .wsdl
+ file.
+
+ Accessing the web service is now very easy as we have a bean
+ factory for it that will expose it as AccountService
+ interface. We can wire this up in Spring:
+
...
]]>
+
From the client code we can access the web service just as if it
was a normal class:
+
- NOTE: The above is slightly simplified in that JAX-WS
- requires endpoint interfaces and implementation classes to be annotated with
- @WebService, @SOAPBinding etc annotations.
- This means that you cannot (easily) use plain Java interfaces and implementation
- classes as JAX-WS endpoint artifacts; you need to annotate them accordingly first.
+
+ NOTE: The above is slightly simplified in
+ that JAX-WS requires endpoint interfaces and implementation classes to
+ be annotated with @WebService,
+ @SOAPBinding etc annotations. This means that you
+ cannot (easily) use plain Java interfaces and implementation classes as
+ JAX-WS endpoint artifacts; you need to annotate them accordingly first.
Check the JAX-WS documentation for details on those requirements.
Exposing web services using XFire
- XFire is a lightweight SOAP library, hosted by Codehaus. Exposing XFire is done using a
- XFire context that shipping with XFire itself in combination with a RemoteExporter-style bean
- you have to add to your WebApplicationContext. As with all
+
+ XFire is a lightweight SOAP library, hosted by Codehaus. Exposing
+ XFire is done using a XFire context that shipping with XFire itself in
+ combination with a RemoteExporter-style bean you have to add to your
+ WebApplicationContext. As with all
methods that allow you to expose service, you have to create a
DispatcherServlet with a corresponding
- WebApplicationContext containing the services you will be
- exposing:
+ WebApplicationContext containing the
+ services you will be exposing:
+
xfire
org.springframework.web.servlet.DispatcherServlet
]]>
- You also have to link in the XFire configuration. This is done by adding a context
- file to the contextConfigLocations context parameter picked up by the
- ContextLoaderListener (or ContextLoaderServlet
- for that matter).
+
+ You also have to link in the XFire configuration. This is done by
+ adding a context file to the contextConfigLocations
+ context parameter picked up by the
+ ContextLoaderListener (or
+ ContextLoaderServlet for that matter).
+
contextConfigLocation
classpath:org/codehaus/xfire/spring/xfire.xml
@@ -800,44 +1028,56 @@ public class AccountServiceEndpoint {
org.springframework.web.context.ContextLoaderListener
]]>
- After you added a servlet mapping (mapping /* to the XFire servlet
- declared above) you only have to add one extra bean to expose the service using XFire.
- Add for example the following configuration in your 'xfire-servlet.xml'
+ After you added a servlet mapping (mapping /*
+ to the XFire servlet declared above) you only have to add one extra bean
+ to expose the service using XFire. Add for example the following
+ configuration in your 'xfire-servlet.xml'
file:
-
-
-
-
-
-
- ]]><!-- the XFire bean is defined in the xfire.xml file -->
-
+ <beans>
-]]>
- XFire handles the rest. It introspects your service interface and generates a WSDL from it.
- Parts of this documentation have been taken from the XFire site; for more detailed information
- on XFire Spring integration, navigate to
- http://docs.codehaus.org/display/XFIRE/Spring.
+ <bean name="/Echo" class="org.codehaus.xfire.spring.remoting.XFireExporter">
+ <property name="serviceInterface" value="org.codehaus.xfire.spring.Echo"/>
+ <property name="serviceBean">
+ <bean class="org.codehaus.xfire.spring.EchoImpl"/>
+ </property>
+ <!-- the XFire bean is defined in the xfire.xml file -->
+ <property name="xfire" ref="xfire"/>
+ </bean>
+
+</beans>
+
+ XFire handles the rest. It introspects your service interface and
+ generates a WSDL from it. Parts of this documentation have been taken
+ from the XFire site; for more detailed information on XFire Spring
+ integration, navigate to http://docs.codehaus.org/display/XFIRE/Spring.
-
+
JMS
- It is also possible to expose services transparently using JMS as the underlying
- communication protocol. The JMS remoting support in the Spring Framework is pretty basic -
- it sends and receives on the same thread and in the
- same non-transactional Session, and as
- such throughput will be very implementation dependent.
- The following interface is used on both the server and the client side.
+
+ It is also possible to expose services transparently using JMS as
+ the underlying communication protocol. The JMS remoting support in the
+ Spring Framework is pretty basic - it sends and receives on the
+ same thread and in the same
+ non-transactional Session, and
+ as such throughput will be very implementation dependent.
+
+ The following interface is used on both the server and the client
+ side.
+
- The following simple implementation of the above interface is used on the server-side.
+
+ The following simple implementation of the above interface is used
+ on the server-side.
+
- This configuration file contains the JMS-infrastructure beans that are shared on both
- the client and server.
+
+ This configuration file contains the JMS-infrastructure beans that
+ are shared on both the client and server.
+
Server-side configuration
- On the server, you just need to expose the service object using the
- JmsInvokerServiceExporter.
+
+ On the server, you just need to expose the service object using
+ the JmsInvokerServiceExporter.
+
]]>
+
Client-side configuration
- The client merely needs to create a client-side proxy that will implement the agreed
- upon interface (CheckingAccountService). The resulting
- object created off the back of the following bean definition can be injected into other
- client side objects, and the proxy will take care of forwarding the call to the
- server-side object via JMS.
+
+ The client merely needs to create a client-side proxy that will
+ implement the agreed upon interface
+ (CheckingAccountService). The resulting
+ object created off the back of the following bean definition can be
+ injected into other client side objects, and the proxy will take care of
+ forwarding the call to the server-side object via JMS.
+
]]>
+
- You may also wish to investigate the support provided by the
- Lingo project, which (to quote the
- homepage blurb) ... is a lightweight POJO based remoting and messaging library
- based on the Spring Framework's remoting libraries which extends it to support JMS.
-
+ You may also wish to investigate the support provided by the Lingo project, which (to quote
+ the homepage blurb)
+ ... is a lightweight POJO based remoting and messaging
+ library based on the Spring Framework's remoting libraries which
+ extends it to support JMS.
+
+
Auto-detection is not implemented for remote interfaces
- The main reason why auto-detection of implemented interfaces does not occur for
- remote interfaces is to avoid opening too many doors to remote callers. The target
- object might implement internal callback interfaces like InitializingBean or
- DisposableBean which one would not want to expose to callers.
-
- Offering a proxy with all interfaces implemented by the target usually does not
- matter in the local case. But when exporting a remote service, you should expose
- a specific service interface, with specific operations intended for remote usage.
- Besides internal callback interfaces, the target might implement multiple business
- interfaces, with just one of them intended for remote exposure. For these reasons,
- we require such a service interface to be specified.
-
- This is a trade-off between configuration convenience and the risk of accidental
- exposure of internal methods. Always specifying a service interface is not too much
- effort, and puts you on the safe side regarding controlled exposure of specific methods.
-
+
+ The main reason why auto-detection of implemented interfaces does
+ not occur for remote interfaces is to avoid opening too many doors to
+ remote callers. The target object might implement internal callback
+ interfaces like InitializingBean or
+ DisposableBean which one would not want to
+ expose to callers.
+
+ Offering a proxy with all interfaces implemented by the target
+ usually does not matter in the local case. But when exporting a remote
+ service, you should expose a specific service interface, with specific
+ operations intended for remote usage. Besides internal callback
+ interfaces, the target might implement multiple business interfaces, with
+ just one of them intended for remote exposure. For these reasons, we
+ require such a service interface to be
+ specified.
+
+ This is a trade-off between configuration convenience and the risk
+ of accidental exposure of internal methods. Always specifying a service
+ interface is not too much effort, and puts you on the safe side regarding
+ controlled exposure of specific methods.
Considerations when choosing a technology
- Each and every technology presented here has its drawbacks. You should carefully
- consider you needs, the services your exposing and the objects you'll be sending
- over the wire when choosing a technology.
-
- When using RMI, it's not possible to access the objects through the HTTP protocol,
- unless you're tunneling the RMI traffic. RMI is a fairly heavy-weight protocol
- in that it support full-object serialization which is important when using a
- complex data model that needs serialization over the wire. However, RMI-JRMP
- is tied to Java clients: It is a Java-to-Java remoting solution.
-
- Spring's HTTP invoker is a good choice if you need HTTP-based remoting but also
- rely on Java serialization. It shares the basic infrastructure with RMI invokers,
- just using HTTP as transport. Note that HTTP invokers are not only limited to
- Java-to-Java remoting but also to Spring on both the client and server side.
- (The latter also applies to Spring's RMI invoker for non-RMI interfaces.)
-
- Hessian and/or Burlap might provide significant value when operating in a
- heterogeneous environment, because they explicitly allow for non-Java clients.
- However, non-Java support is still limited. Known issues include the serialization
- of Hibernate objects in combination with lazily-initialized collections. If you
- have such a data model, consider using RMI or HTTP invokers instead of Hessian.
-
- JMS can be useful for providing clusters of services and allowing the JMS broker
- to take care of load balancing, discovery and auto-failover.
- By default: Java serialization is used when using JMS remoting but
- the JMS provider could use a different mechanism for the wire formatting,
- such as XStream to allow servers to be implemented in other technologies.
-
- Last but not least, EJB has an advantage over RMI in that it supports standard
- role-based authentication and authorization and remote transaction propagation.
- It is possible to get RMI invokers or HTTP invokers to support security context
- propagation as well, although this is not provided by core Spring: There are
- just appropriate hooks for plugging in third-party or custom solutions here.
-
-
-
+ Each and every technology presented here has its drawbacks. You
+ should carefully consider you needs, the services your exposing and the
+ objects you'll be sending over the wire when choosing a technology.
+
+ When using RMI, it's not possible to access the objects through the
+ HTTP protocol, unless you're tunneling the RMI traffic. RMI is a fairly
+ heavy-weight protocol in that it support full-object serialization which
+ is important when using a complex data model that needs serialization over
+ the wire. However, RMI-JRMP is tied to Java clients: It is a Java-to-Java
+ remoting solution.
+
+ Spring's HTTP invoker is a good choice if you need HTTP-based
+ remoting but also rely on Java serialization. It shares the basic
+ infrastructure with RMI invokers, just using HTTP as transport. Note that
+ HTTP invokers are not only limited to Java-to-Java remoting but also to
+ Spring on both the client and server side. (The latter also applies to
+ Spring's RMI invoker for non-RMI interfaces.)
+
+ Hessian and/or Burlap might provide significant value when operating
+ in a heterogeneous environment, because they explicitly allow for non-Java
+ clients. However, non-Java support is still limited. Known issues include
+ the serialization of Hibernate objects in combination with
+ lazily-initialized collections. If you have such a data model, consider
+ using RMI or HTTP invokers instead of Hessian.
+
+ JMS can be useful for providing clusters of services and allowing
+ the JMS broker to take care of load balancing, discovery and
+ auto-failover. By default: Java serialization is used when using JMS
+ remoting but the JMS provider could use a different mechanism for the wire
+ formatting, such as XStream to allow servers to be implemented in other
+ technologies.
+
+ Last but not least, EJB has an advantage over RMI in that it
+ supports standard role-based authentication and authorization and remote
+ transaction propagation. It is possible to get RMI invokers or HTTP
+ invokers to support security context propagation as well, although this is
+ not provided by core Spring: There are just appropriate hooks for plugging
+ in third-party or custom solutions here.
+
+
\ No newline at end of file