Sansür, bir toplumun kendine olan güvensizliğini yansıtır ve otoriter rejimlerin belirgin bir özelliğidir.

--Potter Stewart

30.01.2008

Spring Veri Erişim Katmanı Desteği

1. Giriş


Veri erişim çatısını ayağa kaldırmak, bağlantı açmak, oluşabilecek çeşitli aykırı durumları ele almak ve açılan bağlantıyı kapatmak veri tabanına erişimi sağlayarak gerekli sorguyu çalıştırmak için yapılması gereken belli başlı adımlardır. Çeşitli veri tabanı erişim teknolojileriyle (JDBC, iBATIS, Hibernate, vb.) bütünleşik çalışan Spring erişim çatıları bu adımları soyutlayarak geliştiricinin işini kolaylaştırır. Alt düzey veri erişim görevlerini ele alarak geliştiricinin sadece veri yönetimiyle ilgilenmesine olanak sağlar.


Uygulamanın iş mantığınıyla bağımlılığı azaltmak için ayrı bir katman, veri yönetimini ele alır:




2. Spring Veri Erişim Mantığı


Veri tabanından okuma ve veri tabanına yazma işlemleri DAO (Data Access Objects) sınıfları aracılığıyla yapılır. DAO sınıflarıyla etkileşim DAO arayüzleri ile gerçekleştirilir. Bu yaklaşım sınıflar arası bağımlılığı azalttığı gibi uygulamanın test aşamasında herhangi bir veri erişim gerçekleştirimini kullanmadan, sahte (mock) gerçekleştirimlerle de test edilebilmesini sağlar. Ayrıca koda müdahaleyi en aza indirerek basit JDBC’den karmaşık JPA’ya kadar farklılaşan veri erişim teknolojileri arasında kolayca geçiş yapma olanağı sağlar:





2.1. Spring Veri Erişim Aykırı Durumları


Spring kullanılmadan, saf JDBC ile yazılan kodlarda oluşabilecek aykırı durumlar için sadece java.sql.SqlException zorunlu olarak ele almanız gerekir. Hata herhangi bir sebepten kaynaklanmış olabilir:


  • Uygulama veri tabanı ile erişim kuramamıştır.

  • İşletilen sorgu hatalar içermektedir.

  • Sorguda adı geçen tablo ya da kolon bulunmamaktadır.

  • Eklenmek veya günelenmek istenen veri, veri tabanı kısıtlarına uygun değildir.


Genellikle oluşabilecek hata bağlantı hatası olmasına karşın ortada bir belirsizlik söz konusudur. Spring’in sunduğu çeşitli aykırı durumlar hatanın kaynağına göre fırlatılarak söz konusu belirsizliği ortadan kaldırmaktadır. Ayrıca arka planda kullanılan veri erişim teknolojisine (JDBC, Hibernate, vs.) bağlı olmaksızın bu hatalar aynı şekilde fırlatılmaktadır. Oluşan hatayı ele almak zorunluluk olmaktan çıkarılıp geliştiricinin sorumluluğuna bırakılmıştır:




2.1.2. Veri Erişim Kalıpları(Templates)


Veri tabanıyla etkileşime başlamadan önce bağlantı açma ve işimiz bittiği zaman açılan bağlantıyı kapatma gibi adımlar söz konusudur. Bu adımlar veri ekleme, günleme, sorgulama, vb. farklılaşan işlemlerde hep sabittir.


Spring sabit ve farklılaşan işlemleri ele almak için Template tasarım örüntüsünden faydalanmıştır. Sabit bölümlerde transaction ve kaynak yönetimi ile aykırı durum ele alınırken farklılaşan bölümlerde sorgu deyimi hazırlama, parametre bağlanması ve geri dönüş kümesinin (result set) yönetimi yapılmıştır:



Seçilen veri erişim teknolojisine göre Spring’in sunduğu farklı kalıplar söz konusudur. Veri erişimi için JDBC kullanıyorsanız JdbcTemplate, nesne-ilişkisel eşleşimi (O2R) yapan bir çatı kullanıyorsanız HibernateTemplate veya JpaTemplate kullanımınıza sunulmuştur:



Kullandığınız veri erişimi teknolojisine göre seçtiğiniz kalıp sınıfı Spring bean olarak tanımlayıp uygulama ile veri erişim katmanının bağımlılığını azaltmak için kullandığınız DAO sınıflarınıza bağlamanız gerekmektedir.



2.1.3. DAO Destek Sınıfları


Spring, Template sınıfların yanı sıra Template sınıflarının yönetimini kolaylaştıran ve geliştiricinin, DAO sınıflarını kalıtabildiği DAO destek sınıfları sunmaktadır:



Herbir veri erişim teknolojisi için ayrı bir Template sınıfı sunan Spring herbir Template için de DAO destek sınıfı sunmaktadır:



2.2. Veri Kaynağı Tanımlama


Veri tabanına erişebilmek için öncelikli yapılması gereken bir veri kaynağı tanımlamaktır. Veri kaynağı tanımlamada şu seçeneklerden biri tercih edilebilir:


  • JDBC sürücüsü ile tanımlama

  • JNDI ile tanımlama (Uygulama bağımsız uygulama sunucusundan yönetilebilir.)

  • Bağlantı havuzu tanımlama

Oracle veri tabanı kullanan bir uygulamanın JDBC sürücüsü ile bir veri kaynağı şu şekilde tanımlanır:


<bean id="dataSource"

class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<property name="driverClassName" value="oracle.jdbc.OracleDriver" />

<property name="url"

value="jdbc:oracle:thin:@localhost:1555:test" />

<property name="username" value="admin" />

<property name="password" value="admin" />

</bean>



DriverManagerDataSource ile uygulamanın her bağlantı isteğine yeni bir bağlantı ile cevap verilir. Her bağlantı isteminde yeni bir bağlantı yaratma maliyetli bir işlemdir. SingleConnectionDataSource’da ise bağlantı isteklerine her zaman var olan tek bir bağlantı döndürülür. Bu yüzden multithread uygulamalar için uygun değildir. Geliştirme aşamasında bu tip veri kaynakları kullanılabilmesine rağmen uygulama gerçek kullanım ortamında söz konusu kısıtlar nedeniyle bağlantı havuzu mekanizmasını kullanmalıdır.


Bağlantı havuzu kullanan bir veri kaynağı şu şekilde tanımlanır:


<bean id="dataSource"

class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName" value="oracle.jdbc.OracleDriver" />

<property name="url"

value="jdbc:oracle:thin:@localhost:1555:test" />

<property name="username" value="admin" />

<property name="password" value="admin" />

<property name="initialSize" value="5" />

<property name="maxActive" value="10" />

</bean>


Burada bağlantı havuzu olarak Jakarta Commons Database Connection Pools (DBCP) projesi kullanılmıştır (http://jakarta.apache.org/commons/dbcp).


JdbcTemplate ile veri tabanına JDBC erişiminin nasıl yapılacağı bir diğer blog girdisinde anlatılacaktır.


Template Method Pattern

Bazı adımların gerçekleştirimini altsınıflara bırakarak soyut bir ata sınıfta algoritma iskeleti tanımlanır. Gerçekleştirimi altsınıflara bırakılan bu Template yöntemler algoritmanın ana yapısını değiştirmez.


Böylece alt sınıfların gerçekleştirmesi gereken ortak kod parçaları sarmalanarak hem kod tekrarının önüne geçilerek kodun tekrar kullanılabilirliği hem de algoritma iskeletinde yapılacak bir düzenlemenin tek bir yerden yapılması sağlanmıştır.

Ata sınıfa konulacak ve varsayılan gerçekleştirimi yapılmış bir kanca yöntemle, alt sınıfın algoritmanın akışına müdahale etmesi sağlanabilir:

Bu örneğe göre AtaSınıfı kalıtan bir alt sınıf "kanca" yöntemini aşırıyükleyerek (override) yaptığı kontrol işlemi doğrultusunda "adim3" yöntemini işletip işletmeyeceğine karar verebilir.

26.01.2008

Spring - JSF Bütünleştirmesi

JSF (JavaServer Faces) bilindiği gibi Java masaüstü programcılığında Swing ve AWT’nin uygulama geliştiricilere sunduğu metin alanları, liste kutuları, tab panelleri, grid vb. kullanıcı arayüz bileşenlerinin Web geliştirme ortamında da etkin bir şekilde kullanılmasına olanak veren bir çatıdır. Bu bileşenlerin masaüstü uygulamalarda kullandığı olay-dinleyici (event-listener) mekanizmasını web ortamında da olanaklı kılarak istem/cevap (request/response) mantığını soyutlamıştır. Örneğin formun bir düğmesine tıklama eylemi sunucuda backing beanlerin dinleyici yöntemleri(method) ile ele alınır. Aynı şekilde bir girdi alanının değerinin değişmesi sunucu tarafında bir dinleyici ile ele alınarak gerekli görülen bir akış işletilebilir.

JSF’nin sunduğu bu güçlü kullanıcı arayüzü desteği JSF’nin sunum çatısı olarak kullanılması ve arka plan görevlerin Spring gibi güçlü çatılarla desteklenmesi, web uygulama geliştiriciler için bir seçenek oluşturmuştur. Bu bütünleştirmenin nasıl kolaylıkla yapıldığına bir bakalım:

Elimizde JSF bileşenleri ile hazırlanmış ve kullanıcıdan kayıt bilgileri isteyen bir .jsp kütüğü olsun:

<h:form>

<h2>Register</h2>

<h:panelGrid columns="2">

<f:verbatim><b>First Name:</b></f:verbatim>

<h:inputText value="#{member.firstName}" required="true"/>


<f:verbatim><b>Last Name:</b></f:verbatim>

<h:inputText value="#{member.lastName}" required="true"/>


<f:verbatim><b>E-mail:</b></f:verbatim>

<h:inputText value="#{member.email}" required="true"/>


<f:verbatim><b>Password:</b></f:verbatim>

<h:inputText value="#{member.password}" required="true"/>

...


</h:panelGrid>


<h:commandButton id="submit" action="#{member.register}"

value="Register Member"/>

</h:form>


Spring çatısı gibi JSF de ayar kütüğünde(faces-config.xml) tanımlanan bean tanımlarını kullanır. Burada dikkat edilmesi gereken nokta Spring ve Struts gibi denetim(controller) sınıflarının JSF’de bulunmamasıdır. Yukardaki kod incelendiğinde “Register Member” düğmesine basıldığında işletilecek kod parçası “member” bean’in “register” yöntemidir:


public class Member {


...

public String register() {

memberService.addMember(this);

return "success";

}

}

Member” sınıfının “register” yöntemi, sorumluluğu “memberService”e aktarmıştır. JSF de Spring gibi bağımlılık aktarımı mekanizmasını kullanır. Varsayılan bir değişken çözücü (variable resolver), faces-config.xml kütüğünde tanımlanan beanlerle bağımlılık aktarımını yapar. “MemberService” sınıfının “Member” sınıfına bağımlılık aktarımı şu şekilde gerçekleştirilir:


<managed-bean>

<managed-bean-name>member</managed-bean-name>

<managed-bean-class>

com.model.Member

</managed-bean-class>

<managed-bean-scope>request</managed-bean-scope>

<managed-property>

<property-name>memberService</property-name>

<value>#{memberService}</value>

</managed-property>

</managed-bean>

Geleneksel JSF uygulamasında “memberService” bean ve uygulamanın ihtiyaç duyduğu diğer beanler de faces-config.xml kütüğünde tanımlanır. Bizim hedeflediğimiz ise bean tanımlarını Spring ayar kütüğünde tanımlamak ve JSF’nin bunlara erişimini olanaklı kılmak. JSF’nin varsayılan değişken çözücüsü ile bağımlılık aktarımını kendi içeriğindeki bean tanımlarınıyla yaptığınından bahsetmiştik. Spring içeriğinde bulunan bean tanımlarına JSF erişimini sağlamak için varsayılan değişken çözücüyü değiştirmek bunu başarabiliriz. faces-config.xml kütüğünde Spring’in sağladığı değişken çözücüyü JSF’ye tanıtmak işimizi görecektir:

<application>

<variable-resolver>

org.springframework.web.jsf.DelegatingVariableResolver

</variable-resolver>

</application>

DelegatingVariableResolver ilk olarak JSF beanleri içinde bağımlılığı aktarılacak bean’i arayacak bulamadığı taktirde de Spring beanlerini control edecektir:

<bean id="memberService"

class="com.service.MemberServiceImpl">

<property name="memberDao" ref="memberDao" />

</bean>

JSF sayfalarından Spring uygulama bağlamına (application context) erişim sağlayabilmek için ise varsayılan değişken çözücü tanımını WebApplicationContextVariableResolver olarak ayarlayıp webApplicationContext değişkenini JSF sayfalarında kullanabilirsiniz:


<variable-resolver>

org.springframework.web.jsf.WebApplicationContextVariableResolver

</variable-resolver>

Yukardaki işlemlerin sonrasında Spring beanlerini JSF ile bütünleşik kullanabiliriz. Artık faces-config.xml kütüğünde sayfa yönlendirmelerini yapabilmek için “navigation” kurallarını yazmamız yeterli olacaktır. JSF ile daha ayrıntılı bilgiyi “Manning JavaServer Faces in Action” kitabından edinebilirsiniz.

23.01.2008

Spring ve POJO-tabanlı Uzak Erişim (Remoting) Servisi

1. Giriş

Günümüzde geliştirilen uygulamaların tek başına hizmet üretmeleri uygulamalardan talep edilen gereksinimlerin karşılanması için bazen yeterli olmamaktadır. İstenilen işlevi kendi bünyesindeki servislerle karşılayamayan istemci uygulama, söz konusu işlevi barındıran sunucu nitelikli başka bir uygulamanın servisi ile iletişim kurma gerekliliği duymaktadır. İstemci-sunucu uygulamalar arasında gerçekleştirilen bu iletişim uzak erişim (remoting) adıyla anılır.

Java dünyasında kullanılabilecek birkaç uzak erişim teknolojileri bulunmaktadır:

  • Remote Method Invocation (RMI)

  • Caucho’nun Hessian ve Burlap yöntemleri

  • Spring’in kendi HTTP çağrısı

  • SOAP ve JAX-RPC kullanan Web servisleri

Bu kılavuz belge kapsamında RMI ve Spring HTTPInvoker teknolojilerinden bahsedilecektir.


2. Spring Uzak Erişime Genel Bakış

Spring, adı geçen uzak erişim teknolojilerinin kullanımını oldukça sadeleştirmektedir. Seçilen uzak erişim modelini Spring’in sağladığı ortak bir yapı üzerinden yönetmek kolaylaşmaktadır. Bu ortak yapı sayesinde farklı bir modele geçiş yapmak zahmetsiz hale getirilmiştir.

Tüm modellerde, uzak erişimi sağlanacak servis, yönetilebilir(managed) bean olarak tanımlanır. İstemci bean, proxy aracılığıyla çağrısını yapar. Proxy, uzak servis ile istemci adına iletişime girer. Bağlantı detaylarının sağlanması, uzak çağrının yapılmasını ve dönen sonucun istemciye iletilmesini proxy ele alır. Ayrıca proxy iletişim sırasında oluşan hataları istemcinin isteğe bağlı ele alabilmesi için unchecked hata olarak tekrar fırlatır.

Sunucu tarafında herhangi bir yönetilebilir bean olarak tanımlananan servisi uzaktan erişime açabilirsiniz. Dolayısıyla herhangi bir servis başka bir sınıftan türemeden ya da başka bir arayüzün gerçekleştimini yapmak zorunda olmadan uzak erişim özelliği kazandırılabilir. Servisin, uzak servis olma bilgisi servis koduna bağımlı değildir. Uzak erişim ayarları konfigürasyon kütükleri ile ele alınır.


3. RMI ile Uzak Erişim

RMI, Java geliştiricileri için JDK 1.1’den beri güçlü bir uzak erişim seçeneği sunmaktadır. RMI ile uzak erişim sağlamak biraz zahmetli olmasına karşın Spring hem istemci hem sunucu tarafında zahmeti ortadan kaldırmaktadır. İstemci tarafında proxy factory bean ile sunucu erişimini sağlayacak proxy’i yaratırken sunucu tarafında remote exporter ile uzak erişim sağlanacak Spring yönetilebilir bean servisini adapter örüntüsü yardımıyla RMI servisine dönüştürerek erişime açmaktadır.


3.1. RMI - İstemci Tarafı

Öğrenci Ders kayıt sisteminin ders kaydını öğrencinin harcını yatırmış olması koşuluyla gerçekleştireceğini ve harcın yatırılıp yatırılmadığını da bankanın servisini kullanarak ele alacağı bir örnek düşünelim. Böyle bir senaryoda standard RMI kullanarak uzak servis referansına şu şekilde factory method yazarak erişebilirdik:


private String harcControlUrl = "rmi:/banka/HarcControlService";

public HarcControlService lookupHarcControlService()

throws RemoteException, NotBoundException, MalformedURLException {

HarcControlService harcControlService = (HarcControlService)

Naming.lookup(harcControlUrl);

return harcControlService;

}


Bu yöntem ile fırlatılan checked hatalar ele alınmalı. Ayrıca RMI servisini kullanacak her servis lookupHarcControlService yöntemini çağırmalı. Aynı zamanda istemci kodu, çağırılacak servisin RMI niteliği taşıdığı bilgisinden ve servisin RMI yer bilgisinden de haberdar olmak zorunda. Spring Remoting ile dependency Injection yöntemiyle uzak servisi kullanmak isteyen bir istemciye, servisin uzak veya yerel bilgisinden bağımsız sorumluluk ataması yapılabilir.

Spring’in RmiProxyFactoryBean factory bean’i RMI servisine çağrı yapan proxy’i yaratmakta kullanılabilir. Herhangi bir bean tanımı nasıl yapılıyorsa Spring config kütüğünde gerekli tanımı şu şekilde yapabilirsiniz.


<bean id="harcControlService"

class="org.springframework.remoting.rmi.RmiProxyFactoryBean">


<property name="serviceUrl" value="rmi://${bankahost}/HarcControlService" />

<property name="serviceInterface" value="com.banka.universite.HarcControlService" />

</bean>


Bu tanımda serviceUrl niteliği uzak servisin bulunduğu makine ismini ve servis ismini barındırır. serviceInterface niteliği ise uzak servisin, yerel uygulamada bulunan interface tanımını belirtir. Tanımladığımız bu bean’i uzak servisi kullanacak olan yerel bean’nimizde bağımlılık aktarımı yaparak kullanabilirsiniz:


<bean id="ogrenciKayitService" class="com.yerelUygulama.service.OgrenciKayitServiceImpl">

<property name="harcControlService">

<ref bean="harcControlService"/>

</property>

</bean>

---

import com.banka.universite.HarcControlService


public class OgrenciKayitServiceImpl implements OgrenciKayitService{

private HarcControlService harcControlService;

...

}


Bağımlılık aktarımı sayesinde arka planda çalışan harcControlService gerçekleştiriminde, istemcinin haberi olmadan değişikliğe gitmek mümkün olmaktadır. Buraya kadar yapılan işlemler istemci tarafındaydı. Şimdi de sunucu tarafı işlemlerine bakalım.


3.2. RMI – Sunucu Tarafı

Standard RMI kullanarak uzak servis yazmak için şu adımları izlenir:

  1. java.rmi.RemoteException fırlatan service gerçekleştirimi yazılır.

  2. java.rmi.Remote arayüzünü extend eden service arayüzü yazılır.

  3. İstemci stub ve sunucu skeleton sınıflarını yaratmak için RMI derleyici (rmic) çalıştırılır.

  4. Servisleri barındıracak RMI registry çalıştırılır.

  5. Servisler RMI registry’e bağlanır.

Spring tüm bu adımları sadeleştirmektedir. Geliştirici sadece servisi standard Spring bean olarak hazırlar. RMI’a özel sınıf yazmak zorunda değildir. Dolayısıyla java.rmi.Remote arayüzünden kaynaklı hiçbir yöntemi gerçekleştirmek ya da hataları ele almak zorunda değildir. Servise sadece iş mantığını gerçekleştirmek kalır.


package com.banka.universite;

public interface HarcControlService {

boolean controlOgrenciHarc(int ogrenciNo);

}



package com.banka.universite;

public class HarcControlServiceImpl implements HarcControlService {

public HarcControlImpl() {}

public boolean controlOgrenciHarc(int ogrenciNo) {

boolean harcDurum;

return harcDurum;

}

}


HarcControlImpl sınıfımızı diğer servis sınıflarımız gibi konfigürasyon kütüğüne tanımlıyoruz:


<bean id="harcControlService"

class="com.banka.universite.HarcControlServiceImpl">

</bean>


Gördüğümüz gibi buraya kadar yapılan işlemlerde RMI ile ilgili hiçbir şey yapılmadı. Dolayısıyla servisimiz kendisine uzaktan ya da yerel erişim yapılacağı bilgisini üzerinde barındırmıyor. Diğer servisler gibi geliştirimi yapılan basit bir POJO. Bu servise uzak erişimi sağlamak için stub ve skeleton sınıflarını oluşturacak rmic kullanmak ve RMI registry’e eklemek yerine tüm işleri soyutlandıran Spring’in RmiServiceExporter’ını kullanacağız.

RmiServiceExporter Spring yönetilebilir bean’leri RMI servisleri olarak dışarı açar. Bunu da ilgili bean’i adapter örüntüsü ile sağlar. Adapter sınıfı servisin RMI registry’e bağlanması ve gelen istemleri sarmaladığı servise aktarmakla sorumludur. Çalışan bir RMI registry varsa servisi ona bağlar, eğer yoksa yeni bir RMI registry başlatır.

Servisi uzak erişime açmak için yapılması gereken ayarlar oldukça basittir:


<bean class="org.springframework.remoting.rmi.RmiServiceExporter">

<property name="service" ref="harcControlService"/>

<property name="serviceName" value="HarcControlService"/>

<property name="serviceInterface" value="com.banka.univeriste.HarcControlService"/>

</bean>



4. Spring HTTP Invoker ile Uzak Erişim

RMI ile uzak erişimde eğer arada güvenlik duvarı var ise iletişim sağlanamaz. Güvenlik duvarını geçmek için Spring, nesnelerin Http ile gönderilebilmesini olanaklı kılan ve RMI gibi Java Serialization mekanizmasını kullanan HTTP Invoker modelini geliştirmiştir. HTTP Invoker tabanlı uzak erişim sistemi geliştirimi, RMI-Spring’e çok benzemektedir.


4.1. HTTP Invoker - İstemci

RMI servisine ulaşmak için RmiProxyFactoryBean kullandığımız gibi HTTP invoker servisine ulaşmak için de HttpInvokerProxyFactoryBean kullanıyoruz. Yapılması gereken bean tanımı da RMI’dan pek farklı değil:


<bean id="harcControlService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">

<property name="serviceUrl">

<value>

http://${serverName}/${contextPath}/harcControlService.remote

</value>

</property>

<property name="serviceInterface">

<value>com.banka.universite.HarcControlService</value>

</property>

</bean>


Bu işlemin ardından istemde bulunacak yerel servisimize harcControlService bean’i bağımlılık aktarımı yöntemiyle bağlayabiliriz.



4.2. HTTP Invoker – Sunucu

Uzak erişim için kullanacağımız servisi RMI’da olduğu gibi standard bir bean gibi geliştirip bean tanımını yapıyoruz. Ardından servisimizi uzak erişime açmak için RMI’da olduğu gibi HttpInvokerServiceExporter ile sarmalıyoruz. HttpInvokerServiceExporter bir Spring MVC controller’ıdır. Sunucuya istemciden gelen istem DispatcherServlet aracılıyla HttpInvokerServiceExporter’a aktarılır. Oradan da ilgili servise ulaşılır:


HttpInvokerServiceExporter’ın Spring MVC controller olması sebebiyle projemizin DispatcherServlet-servlet.config.xml ayar kütüğünde tanımlanması gerekir:


<bean name="/harcControlService.remote"

class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">

<property name="service">

<ref bean="harcControlService"/>

</property>

<property name="serviceInterface">

<value>com.banka.universite.HarcControlService</value>

</property>

</bean>


HttpInvokerServiceExporter Controller arayüzünden değil de HttpRequestHandler arayüzünden gerçekleştirilmiştir. DispatcherServlet için varsayılan tanımları ezecek herhangi bir "HandlerAdapter" bean tanımı yapılmışsa HttpInvokerServiceExporter'ın DispatcherServlet ile iletişim kurabilmesi için aşağıdaki adapter tanımı da eklenmelidir:

<bean

class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>

Yukarıdaki örneğe göre projemizin web.xml tanımında DispatcherServlet'i tetikleyecek tanımın yapılması da gerekir:

<servlet-mapping>

<servlet-name>DispatcherServlet</servlet-name>

<url-pattern>*.remote</url-pattern>

</servlet-mapping>

Spring HTTP Invoker modeli, HTTP iletişimini kullanması ve Java Serialization mekanizmasını desteklemesi ve yazılan uzak servislerin sıradan Spring yönetilebilir bean olarak geliştirilmesi sebebiyle uzak erişimde kolaylıkla kullanılabilecek bir seçenektir. Spring HTTP Invoker modelinin tek kısıtı, istemci ve sunucu uygulamaların Spring tabanlı uygulamalar olması gerekliliğidir. Yukarda anlatılan yöntemler sonucunda istemci uygulama uzak servis yöntemini sanki kendi yerelindeymiş gibi çağırabilir.