RMI在Spring中的使用之Hessian,BurlapServiceExporter

這兩種實現都是基於http的,只不過Hessian使用二進制格式,Burlap使用XML格式傳輸文件。在4.x的Spring中官方已經將Burlap做爲廢棄類,配置和Hessian相同,下面詳細講下HessianServiceExporterjava

咱們首先先試着寫下運行程序web

服務端
spring

rmi.xml
瀏覽器

<bean id="accountService" class="example.AccountServiceImpl">
    </bean>
<bean name="accountExporter" class="org.springframework.remoting.caucho.HessianServiceExporter">
        <property name="service" ref="accountService"/>
        <property name="serviceInterface" value="example.AccountService"/>
    </bean>
<!-- 也能夠用下面的方法 -->
<bean name="/AccountService" class="org.springframework.remoting.caucho.HessianServiceExporter">
        <property name="service" ref="accountService"/>
        <property name="serviceInterface" value="example.AccountService"/>
    </bean>

上面兩種方法主要是由於Spring mvc的BeanNameUrlHandlerMapping會自動將其處理,若是使用其餘框架(例如實現Struts2的攔截器)就必須本身實現或者使用第二種方式
mvc

web.xml中添加,由於首先是Springmvc先啓動,因此設置較後一些
app

<servlet>
        <servlet-name>accountExporter</servlet-name>
        <servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>accountExporter</servlet-name>
        <url-pattern>/remoting/*</url-pattern>
    </servlet-mapping>

並在maven中加入依賴框架

<dependency>
            <groupId>com.caucho</groupId>
            <artifactId>hessian</artifactId>
            <version>4.0.38</version>
        </dependency>

記得必定要添加spring-webmvc和spring-web,不然沒法運行,由於web程序須要這兩個包
maven

客戶端ide

<bean id="accountService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
        <property name="serviceUrl" value="http://localhost:8080/remoting/AccountService"/>
        <property name="serviceInterface" value="example.AccountService"/>
    </bean>

一樣要添加spring-web和hessian依賴,只是比上邊少了mvc包而已,它不須要公開接口,web包包含了client的訪問,因此必需要要加入
post

當咱們用客戶端請求的時候會發現出現了RMI Test!


當咱們用瀏覽器的get方法請求會出現以下信息:

type Status report

message HessianServiceExporter only supports POST requests

description The specified HTTP method is not allowed for the requested resource.

必須是post。咱們來看下HessianServiceExporter的實現

public class HessianServiceExporter extends HessianExporter implements HttpRequestHandler {

    /**
     * Processes the incoming Hessian request and creates a Hessian response.
     */
    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //判斷方法,是不是post若是不是則相應錯誤消息,HessianServiceExporter only supports POST requests
        if (!"POST".equals(request.getMethod())) {
            throw new HttpRequestMethodNotSupportedException(request.getMethod(),
                    new String[] {"POST"}, "HessianServiceExporter only supports POST requests");
        }
        //設置請求類型爲application/x-hessian
        response.setContentType(CONTENT_TYPE_HESSIAN);
        try {
          //這裏主要就是執行調用導出的對象。
          invoke(request.getInputStream(), response.getOutputStream());
        }
        catch (Throwable ex) {
          throw new NestedServletException("Hessian skeleton invocation failed", ex);
        }
    }

}

一樣咱們在瀏覽器調用post方法,則會拋出異常。


那麼Hessian的遠程調用比直接調用RmiProxyFactoryBean有什麼好處呢?

首先它是基於http的,因此它就有了http的全部特性,那麼咱們就能夠對其url進行權限控制,這樣,咱們就能夠進行控制,同時經過閱讀HessianProxyFactoryBean類源碼,在父類HessianClientInterceptor發現了以下代碼

/**
     * Set the username that this factory should use to access the remote service.
     * Default is none.
     * <p>The username will be sent by Hessian via HTTP Basic Authentication.
     * @see com.caucho.hessian.client.HessianProxyFactory#setUser
     */
    public void setUsername(String username) {
        this.proxyFactory.setUser(username);
    }

    /**
     * Set the password that this factory should use to access the remote service.
     * Default is none.
     * <p>The password will be sent by Hessian via HTTP Basic Authentication.
     * @see com.caucho.hessian.client.HessianProxyFactory#setPassword
     */
    public void setPassword(String password) {
        this.proxyFactory.setPassword(password);
    }

最後經過閱讀官方文檔,其是支持spring-security,

官方給出的配置方式以下:

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors" ref="authorizationInterceptor"/>
</bean>
<bean id="authorizationInterceptor"
class="org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor">
<property name="authorizedRoles" value="administrator,operator"/>
</bean>

到此,HessianServiceExporter的使用也就結束了,有時間在研究下和spring-security集成了

相關文章
相關標籤/搜索