1. 程式人生 > >Spring 與Hessian 整合的簡單遠端呼叫例項

Spring 與Hessian 整合的簡單遠端呼叫例項

這幾天一直在學習遠端呼叫只是,今天學習spring與hessian整合釋出遠端服務,研究了一天,各種錯誤,各種網上找答案。皇天不負有心人,總算整合出一個簡單的demo。不多說直接,來點有營養的!
因為Hessian是基於Http協議的框架,所以服務端是一個web程式,結構如下
這裡寫圖片描述
pom.xml依賴如下

<dependencies>
        <dependency>
            <groupId>com.caucho</groupId>
            <artifactId>hessian</artifactId
>
<version>4.0.7</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> <dependency
>
<groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId
>
spring-orm</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.0.5.RELEASE</version> </dependency> </dependencies>

實體類spitter.java

package com.spittr.entity;

import java.io.Serializable;

public class Spitter implements Serializable {

  /**
     * 
     */
    private static final long serialVersionUID = 1563056272025335248L;
private Long id;
  private String username;

  private String password;

  private String firstName;

  private String lastName;

  private String email;

  public Spitter() {}

  public Spitter(String username, String password, String firstName, String lastName, String email) {
    this(null, username, password, firstName, lastName, email);
  }

  public Spitter(Long id, String username, String password, String firstName, String lastName, String email) {
    this.id = id;
    this.username = username;
    this.password = password;
    this.firstName = firstName;
    this.lastName = lastName;
    this.email = email;
  }

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  public String getEmail() {
    return email;
  }

  public void setEmail(String email) {
    this.email = email;
  }

}

spring 配置類

package com.spittr.config;

import java.util.Properties;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.remoting.caucho.HessianProxyFactoryBean;
import org.springframework.remoting.caucho.HessianServiceExporter;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;

import com.caucho.hessian.client.HessianProxyFactory;
import com.spittr.remote.SpitterService;

@Configuration
@ComponentScan(basePackages = { "com.spittr.*" })
@EnableWebMvc
public class MainConfig {

    // 建立hessian服務釋出器,因為hessian是基於http的遠端協議,因為需要釋出為web應用
    @Bean
    public HessianServiceExporter hessianExportSpitterService(SpitterService spitterService) {
        // Hessian沒有登錄檔,因此也就沒必要為Hessian服務進行命名
        HessianServiceExporter exporter = new HessianServiceExporter();
        exporter.setService(spitterService);
        exporter.setServiceInterface(SpitterService.class);
        return exporter;
    }
    //配置hessian對映處理器
    @Bean
    public HandlerMapping hessianMapping() {
        SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
        Properties mappings = new Properties();
        mappings.setProperty("/spitter.service", "hessianExportSpitterService");
        handlerMapping.setMappings(mappings);
        return handlerMapping;
    }
}

配置對映處理器,將/spitter.service 的請求轉發到hessianExportSpitterService處理。
注意:這裡handlerMapping 是SimpleUrlHandlerMappig,根據name來查詢bean的,所以
可以看得出配置釋出服務HessianServiceExporter 與Spring整合的java rmi遠端程式碼很相似。

spring的配置檔案

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/security   
        http://www.springframework.org/schema/security/spring-security-3.2.xsd">
       <!-- 啟動註解 --> 
    <context:annotation-config></context:annotation-config>
    <!-- 匯入配置類 -->
    <beans:bean class="com.spittr.config.MainConfig"></beans:bean>
</beans:beans>

因為原先用的是java配置Spring,在這裡直接將java配置匯入到Spring xml配置中
web.xml如下

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
  <welcome-file-list>
      <welcome-file>index.html</welcome-file>
  </welcome-file-list>
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/springmvc-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!-- <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.service</url-pattern>
    </servlet-mapping> -->
</web-app>

服務類

package com.spittr.remote;

import java.util.List;

import com.spittr.entity.Spitter;

public interface SpitterService {
    public List<Spitter> getRencentSpitters(int count);

    public void saveSpitter(Spitter spitter);

    public Spitter getSpitter(long id);
}

實現類

package com.spittr.service;

import java.util.List;

import org.springframework.stereotype.Service;

import com.spittr.entity.Spitter;
import com.spittr.remote.SpitterService;
@Service
public class SpitterServiceImp implements SpitterService {

    public SpitterServiceImp() {
        // TODO Auto-generated constructor stub
    }

    @Override
    public List<Spitter> getRencentSpitters(int count) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void saveSpitter(Spitter spitter) {
        System.out.println("save done");
    }

    @Override
    public Spitter getSpitter(long id) {
        Spitter spitter = new Spitter();
        spitter.setUsername("spitter " +id);
        spitter.setId(id);
        System.out.println(spitter.getUsername());
        System.out.println(spitter);
        return spitter;
    }


}

啟動tomacat併發布服務。

服務端專案結構
這裡寫圖片描述
pom.xml

<dependencies>
        <dependency>
            <groupId>com.caucho</groupId>
            <artifactId>hessian</artifactId>
            <version>4.0.7</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
    </dependencies>

實體類與介面與服務端一直,同時注意包名的一致性。
Spring 配置類


package com.spittr.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.remoting.caucho.HessianProxyFactoryBean;

import com.spittr.remote.SpitterService;

@Configuration
@ComponentScan(basePackages={"com.spittr.*"})
public class MainConfig {
    @Bean(name="spitterService")
    public HessianProxyFactoryBean spitterService(){
        HessianProxyFactoryBean proxyFactoryBean = new HessianProxyFactoryBean();
        proxyFactoryBean.setServiceUrl("http://localhost:8888/SpringHessianDemo/spitter.service");
        proxyFactoryBean.setServiceInterface(SpitterService.class);
        return proxyFactoryBean;
    }
}

利用Spring容器獲得一個遠端代理工廠例項HessianProxyFactoryBean 。proxyFactoryBean提供了getObject方法,返回被代理的一個例項。
測試類:


package spittr.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.remoting.caucho.HessianProxyFactoryBean;

import com.spittr.config.MainConfig;
import com.spittr.entity.Spitter;
import com.spittr.remote.SpitterService;


public class ClientTest {

    @Test
    public void clientTest(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        HessianProxyFactoryBean bean = applicationContext.getBean(HessianProxyFactoryBean.class);
        SpitterService spitterService=(SpitterService) bean.getObject();
        Spitter spitter = spitterService.getSpitter(2);
        System.out.println(spitter);
    }
}

測試結果
客戶端
這裡寫圖片描述
服務端
這裡寫圖片描述
測試成功!