2012-06-18 3 views
3

Я следил за учебником для весеннего отдыха, в частности HttpInvokerServiceExporter, и у меня нет проблем с настройкой как клиента, так и сервера (factorybean).URL-адрес перенаправления перенапряжений весной

Вопрос, я заметил, используя Spring MVC, каждый интерфейс отображается на определенный URL

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
     <property name="mappings"> 
      <props> 
       <prop key="hello.htm">test_service</prop> 
      </props> 
     </property> 
    </bean> 

    <!-- *********************exposed web services*************************--> 
    <bean name="test_service" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> 
     <property name="serviceInterface" value="foo.webservices.HelloServiceInterface" /> 
     <property name="service"> 
      <ref bean="helloService"></ref> 
     </property> 

вопрос, если у меня есть более чем 1 метод в моем интерфейсе сервиса, можно отобразить каждый из этих методов интерфейса к самому URL?

ответ

4

Идея, лежащая в основе HTTPInvokerServiceExporter, заключается в предоставлении конечной точки для приема вызова метода удаления.

На сервере стороны было бы просто, как настроить RemoteExporter, объявляя интерфейс, который вы хотите, чтобы разоблачить и связать его с реальным боба, который будет обрабатывать вызовы.

На клиентском необходимо настроить RemoteAcessor, который в основном нуждается в интерфейсе, который будет иметь доступ на стороне сервера.

Реализация через HTTP может быть сделано с помощью HttpInvokerServiceExporter на стороне сервера, как в следующем примере:

служба Интерфейс:


package foo.bar.services; 

public interface MyService { 

    public int sum(int num1, int num2); 

} 

За эту услугу вы бы реализацию (скажем, foo.bar.services.DefaultMyService).

Экспозиция и конфигурации от контекста ярового будут выглядеть так:


<bean name="myService" class="foo.bar.DefaultMyService" /> 
<bean name="/myService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> 
    <property name="service" ref="myService"/> 
    <property name="serviceInterface" value="foo.bar.MyService"/> 
</bean> 

С этой конфигурацией я просто намеревался иметь экземпляр моей реализация MyService подвергаясь под foo.bar.MyService интерфейсом по URL, отображаемого /myService (bean name) в самом простом случае с использованием BeanNameUrlHandlerMapping, который не делает ничего, кроме как сопоставить URL-адрес компонента со значением URL (этот случай /myService).

На стороне клиента (потребителя) у вас будет настроен компонент, просто объявляющий интерфейс, который вы ожидаете от удаленной стороны. Для нашей службы было бы что-то вроде:

<bean id="httpInvokerProxy" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"> 
    <property name="serviceUrl" value="http://foo.bar.org/springSample/myService"/> 
    <property name="serviceInterface" value="foo.bar.MyService"/> 
</bean> 

На данный момент весной экземпляр фасоли на стороне клиента, прокси экземпляра и каждый вызов метода будет затем сериализуются и передаются по протоколу HTTP к конечной точке (в данном случае http://foo.bar.org/springSample/myService На стороне сервера этот запрос десериализуется и интерпретируется, т. Е. Вызывает метод на реальном обслуживаемом объекте (в нашем случае DefaultMyService). Служба вернет то, что будет сериализовано, как результат, в HTTP-запрос, выполняемый клиентом. Клиент получит его и десериализует его и возвращает в исходный метод invocator.

Как вы можете видеть (и полученное от S Принг документация):

сторона сервера

Десериализует удаленные объекты Призыва и упорядочивает удаленные результат вызова объектов. Использует сериализацию Java точно так же, как RMI, но обеспечивает такую ​​же легкость настройки, как протоколы Husian на основе HTTP Hessian и Burlap.

сторона клиент

Сериализует удаленные объекты Призыва и десериализует удаленные результат вызова объектов. Использует сериализацию Java точно так же, как RMI, но обеспечивает такую ​​же легкость настройки, как протоколы Husian на основе HTTP Hessian и Burlap.

сериализации, используемый с Spring Remoting на этом случае является сериализация, то есть запрос HTTP держит тело лица, содержащее сериализованный объект (это хорошо иметь в виду, что в этом случае JVM версии и класса версий должна быть совместимый).

Экспозиция выполнена в целом, вы не можете ее разделить, имея один URL для каждого метода этого интерфейса. Поэтому было бы проще использовать Spring MVC и создать контроллер (@Controller) реализовать метод для каждого метода, который у вас есть на вашем интерфейсе, аннотируя его как (с желаемым URL-адресом) и вызывать метод в службе следующим образом:

контроллер образца


package foo.bar; 

import foo.bar.service.MyService; 

@Controller 
public class MyService { 
    @Autowired 
    private MyService myService; 

    @RequestMapping("/sum/{num1}/{num2}") 
    public int sum(@PathVariable("num1") int num1, @PathVariable("num2") int num2) { 
     return myService.sum(num1, num2); 
    } 

} 

Использование конфигурации контекста

<context:component-scan base-package="foo.bar"/> 

было бы карту т классы, найденные на foo.bar и под пакетами автоматически, то есть реализация Service (DefaultMyService) может быть сопоставлена ​​@Service и @Autowired контроллеру, как это сделано в образце, без какой-либо конфигурации компонента в контексте xml.

Но это будет предоставлять вашу услугу через интерфейс REST, то есть он будет обрабатывать простые HTTP-запросы, которые могут быть сделаны другими потребителями, такими как пользователь PHP (это не может быть сделано с помощью Spring Remoting, поскольку использует чистую сериализацию Java).

Если ваш клиент является Java, вы можете окончательно использовать Remoting и выставить свою службу в целом, если не реализация REST с использованием Spring MVC является хорошим решением.

Spring Documentation можно найти here

+0

Что мне нужно знать. благодаря! – goh

1

Я действительно рекомендую определить ваши контроллеры с помощью аннотации @Controller. С Spring documentation начните с добавления сканирования компонентов в конфигурацию Spring.

<context:component-scan base-package="your.package.path"/> 

Тогда в классе, скажем, your.package.path.WhateverController, аннотировать класс:

@Controller 
WhateverController 

И аннотировать методы с @RequestMapping:

@RequestMapping(value = "/helloWorld") 
public ModelAndView helloWorld() { 
... 
} 

@RequestMapping(value = "/project/{projectId}") 
public ModelAndView helloWorld(@PathVariable String projectId) { 
... 
} 

Это об этом, несколько сопоставлений на контроллер.

+0

эй стив, делает это работает с HttpInvokerServiceExporter – goh

+0

Есть ли какой-либо причине вы привязаны к этому классу? – stevedbrown

+0

главным образом из-за сериализации Java. – goh

1

Я думаю, вам нужно сказать нам, что вы пытаетесь сделать в первую очередь. Если вы предоставляете свои услуги универсальному веб-клиенту, лучшим вариантом будет REST или SOAP; если вы подвергаете свои услуги другому весеннему бобам в другом приложении, то Spring Remoting может быть достаточно.

Комментарий «выставленные веб-сервисы» в вашем конфигурационном файле весны кажется непонятным для вашей цели.

Когда вы предоставляете услугу удаленным клиентам, вам всегда необходимо предоставить договор, чтобы удаленные клиенты знали, что возможно. REST предоставляет этот контракт с использованием URL; SOAP предоставляет этот контракт с использованием WSDL; и Spring Remoting прямо дает клиенту контракт с java-интерфейсом, поэтому клиент может вставлять этот интерфейс в свои собственные компоненты и использовать его как локально определенный компонент.

В вашем вопросе, который вы упомянули о сопоставлении метода с URL-адресом, Spring Remoting не может этого сделать, поскольку он предоставляет intefaces; то, что вы хотите сделать, очень понравилось мне. И я согласен с @stevebrown, если вы используете свои службы с помощью сопоставленного контроллера, это хороший подход.

+0

за рекомендацию! – goh

Смежные вопросы