Прост пролетен пример за отдалечаване на HTTP

Използвам този запис в блога, за да демонстрирам на прост пример използването на HTTP Remoting на Spring Framework. Има многобройни онлайн ресурси по този въпрос, така че намерението ми тук е да предоставя изключително проста, но пълна демонстрация на използването на Spring's HTTP Remoting с клиенти, които не са браузъри.

Подходът Spring към HTTP Remoting позволява на клиентите да комуникират с хоствания на Spring сървър кода чрез HTTP, без клиентският код да изисква каквото и да е познаване на HTTP. Вместо това клиентският Java код "вижда" само нормални бизнес обекти, свързани с Java (обикновено интерфейси), а не специфични за HTTP обекти.

Spring HTTP Remoting обикновено изисква Spring и Java както от страна на сървъра, така и от страна на клиента. Ако обаче тези две изисквания могат да бъдат изпълнени, Spring HTTP Remoting се прилага лесно.

Следващите стъпки позволяват HTTP комуникация между хоствани от Spring клиенти и сървъри. След като първо накратко очертах стъпките, след това ще се задълбоча в тях по-подробно (включително примерни кодове).

  1. Създайте или използвайте съществуващ Spring bean, който обикновено реализира Java интерфейс.

    Това не е нищо особено за дистанционното HTTP и е същата стъпка, която трябва да направите, за да направите повечето неща през пролетта (забележително изключение е

    Пролетен JDBC

    което не изисква да се използват пролетни зърна).

  2. Създайте конфигурационния файл Spring XML за свързване на боб, създаден в стъпка # 1, с контекст на приложение Spring.

    Както при стъпка 1, този XML файл не е нищо особено за пролетното HTTP Remoting, но вместо това е общ за почти всички кабелни и конфигурационни системи на Spring Framework.

  3. Създайте или добавете към web.xmlфайл.

    Тази трета стъпка е първата стъпка, която е по-специфична за Spring HTTP Remoting, но все още е общоприложима с

    Пролетна MVC рамка

    . Тази стъпка включва добавяне на клас на сървлет и съпоставяне на URL, както обикновено се използва с

    Java EE

    сервлети

    и

    JavaServer Pages

    . Най-важната част от тази стъпка е да посочите пролетта

    DispatcherServlet

    . В това е предоставена и незадължителна "връзка"

    web.xml

    файл до местоположение на контекстна конфигурация, където се намират и използват един или повече контекстни файлове на XML приложение Spring.

  4. Създайте специфичния за пролетта контекстен файл на сървлета.

    Този XML файл много прилича на "нормален" XML конфигурационен файл за контекст на пролетното приложение, но името му се предписва от конвенцията за името на сървлета, последвано от хипер и думата сървлет. С други думи, ако сървлетът беше наречен "somewebthing" в

    web.xml

    файл, ще се извика този конфигурационен файл на пролетния сървлет

    somewebthing-servlet.xml

    . Този файл съдържа конфигурацията за

    HttpInvokerServiceExporter

    (част от това, което е специално за HTTP Remoting, обхванато в този запис в блога) и информация за картографиране на URL адреси.

  5. Тест!

    Въпреки че простият клиент ще пише без HTTP предвид и ще изглежда, че използва само Java обекти, той всъщност ще извиква услугата чрез HTTP. Това ще бъде „доказано“ чрез стартиране на клиента без внедряване на услугата и следене на получения HTTP код за грешка.

Сега ще продължа да демонстрирам по-подробно горните стъпки и ще се опитам да ги илюстрирам конкретно с примерни кодове.

Стъпка 1: Bean и неговият интерфейс

Тази стъпка не е по-различна от дефинирането на Java класове и интерфейси, които те прилагат за използване с Spring. Следните списъци с кодове показват интерфейса ( StateCapitalServiceIF) и прилагащия клас ( StateCapitalService), използван за този пример.

--- StateCapitalServiceIF.java ---

package examples.springhttp; import java.io.Serializable; /** * The State Capital Service interface that the client will use to access * server-side functionality via HTTP. */ public interface StateCapitalServiceIF extends Serializable { /** * Provide capital of state whose name is provided. * * @param stateName Name of state whose capital is desired. * @return Capital of the specified state; null if not found. */ public String getCapital(final String stateName); } 

--- StateCapitalService.java ---

package examples.springhttp; import java.util.Map; /** * Implementation of functionality to be run after being called by client via * HTTP. */ public class StateCapitalService implements StateCapitalServiceIF { Map statesAndCapitals = null; public StateCapitalService() { } /** * Set my states to state capitals mapping. * * @param statesAndCapitals States to state capitals mapping. */ public void setStatesAndCapitals(final Map statesAndCapitals) { this.statesAndCapitals = statesAndCapitals; } /** * Provide capital of state whose name is provided. * * @param stateName Name of state whose capital is desired. * @return Capital of the specified state; null if not found. */ public String getCapital(final String stateName) { return this.statesAndCapitals.get(stateName); } } 

Стъпка 2: Конфигурационен файл за контекст на пролетното приложение

Харесва ми да поддържам специфичната за HTTP конфигурация на Spring отделно от XML конфигурацията на боб. Следователно конфигурацията на боб е точно такава, каквато би се виждала нормално с Spring. За да конфигурирате StateCapitalServiceкласа по-горе, се използва следната конфигурация:

--- spring-http-config.xml ---


    

So far, nothing specific to HTTP Remoting has been done. In fact, the bean, its interface, and its XML application context configuration could all be run by a normal Java SE class like the one shown below:

--- MainServiceAppContext.java ---

package examples.springhttp; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Demonstrates how Spring bean can be used without any HTTP involvement. */ public class MainServiceAppContext { public static void printStateInfo( final StateCapitalServiceIF stateCapitalMapper, final String state) { System.out.println( "The capital of " + state + " is " + stateCapitalMapper.getCapital(state)); } /** * @param args the command line arguments */ public static void main(String[] args) { final ApplicationContext context = new ClassPathXmlApplicationContext( "examples/springhttp/spring-http-config.xml" ); StateCapitalServiceIF stateCapitalMapper = (StateCapitalServiceIF) context.getBean("stateCapitalService"); printStateInfo(stateCapitalMapper, "Alabama"); printStateInfo(stateCapitalMapper, "Colorado"); } } 

Step #3: The web.xml File

This web.xml file is familiar to anyone who has developed a Java EE web application. The web.xml used in this example is shown next.


    
      Simple Spring HTTP Remoting Example This is meant as an extremely simple example of using Spring's HTTP Remoting capability. statesCapitals org.springframework.web.servlet.DispatcherServlet 1 statesCapitals /statesCapitals org.springframework.web.context.ContextLoaderListener contextConfigLocation /WEB-INF/examples/springhttp/spring-http-config.xml 
    

Step #4: The Servlet Context Configuration File

Because the servlet in this example is named "statesCapitals," a Spring servlet configuration file named statesCapitals-servlet.xml needs to be provided. It is shown next:

--- statesCapitals-servlet.xml ---


    
      examples.springhttp.StateCapitalServiceIF httpStateCapitalService 
    

Step #5: Testing It

Трябва да конфигурираме клиента да комуникира чрез HTTP с нашето сървърно приложение. Конфигурацията за това се съдържа в spring-http-client-config.xmlза този пример и е показана по-нататък:

--- spring-http-client-config.xml ---


    
      //localhost:8080/SpringHTTPExample/statesCapitals examples.springhttp.StateCapitalServiceIF 
    

Клиентският код, който използва горния XML за зареждане на Spring контейнер и извикване на кода от страна на сървъра чрез HTTP, е в класа HttpClientи този код е показан след това:

--- HttpClient.java ---

package examples.springhttp.client; import examples.springhttp.StateCapitalServiceIF; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * This class demonstrates a client of a Spring HTTP-exposed service and shows * how the client interacts with the server as if using normal Java objects * rather than using anything HTTP specific. */ public class HttpClient { public static void printStateInfo( final StateCapitalServiceIF stateCapitalMapper, final String state) { System.out.println( "The capital of " + state + " is " + stateCapitalMapper.getCapital(state)); } public static void main(final String[] arguments) { final ApplicationContext context = new ClassPathXmlApplicationContext( "examples/springhttp/client/spring-http-client-config.xml"); final StateCapitalServiceIF stateCapitalService = (StateCapitalServiceIF) context.getBean("stateCapitalProxyService"); printStateInfo(stateCapitalService, "Colorado"); printStateInfo(stateCapitalService, "Alabama"); } }