Spring整合Hessian

最近项目用到了Hessian,初次接触于是花时间研究了下。现记录Spring & Hessian的整合过程,至于Hessian是什么就不在此解释了(一款轻量级RMI框架)。

 

1.新建Dynamic Web Project(HessianDemo)

2.加入SpringFramework-3.x和hessian-4.0.38.jar,以及其他需要的jar包(根据实际情况在此不赘述,aopalliance、common-logging之类的)。

3.建立接口文件(主要是红框里的三个):

 

LichService.java:

package com.lichmama.demo.hessian.service;

public interface LichService
{
    public String sayHello(String name);
}

HessianServiceImpl.java:

package com.lichmama.demo.hessian.impl;

import org.springframework.stereotype.Service;

import com.lichmama.demo.hessian.service.LichService;

@Service
public class HessianServiceImpl implements LichService
{

    @Override
    public String sayHello(String name)
    {
        if (name == null || name.isEmpty()) {
            name = "anonymous";
        }
        return "hello, " + name;
    }

}

AuthHessianServiceExporter.java:

package com.lichmama.demo.hessian.exporter;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.remoting.caucho.HessianServiceExporter;

import com.lichmama.common.utils.SecurityTool;

//继承HessianServiceExporter可完成一些自定义的工作,如鉴权、预处理、日志、事务管理什么的
public class AuthHessianServiceExporter extends HessianServiceExporter
{
    //密匙,用来验证访问者是否具有访问权限
    private final static String authorization = "e807f1fcf82d132f9bb018ca6738a19f"; //加密后的密码:1234567890
    
    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        //从Header里直接取出验证密匙
        String requestAuth = request.getHeader("Authorization");
        
        //如果存在且符合我们的期望则允许其访问,否则可自行编辑响应报文
        //当然,密码可以稍微加密啥的(DES、AES、SHA1、MD5)
        if (requestAuth == null || requestAuth.isEmpty()) {
            System.out.println("[Authorization] header not existing");
            throw new ServletException("[Authorization] header not existing");
        } else {
            //对比加密后的密码
            if (!authorization.equals(SecurityTool.getMD5Hash(requestAuth))) {
                System.out.println("unexpected authorization key");
                throw new ServletException("unexpected authorization key");
            }
        }
        
        //鉴权成功,则继续流转下去。控制权交回HessianServiceExporter
        super.handleRequest(request, response);
    }

    public static String getAuthorization()
    {
        return authorization;
    }
}

*SecurityTool.java: 

package com.lichmama.common.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SecurityTool
{
    public static final char[] table = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    
    public static String getMD5Hash(String plain)
    {
        byte[] bytes = plain.getBytes();
        MessageDigest md5;
        try
        {
            md5 = MessageDigest.getInstance("MD5");
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
            return null;
        }
        byte[] md5bytes = md5.digest(bytes);
        char[] hashcode = new char[md5bytes.length * 2];
        for (int i=0, j=0; i<md5bytes.length; i++) 
        {
           byte bt = md5bytes[i];
           hashcode[j++] = table[bt >>>4 & 0xf];
           hashcode[j++] = table[bt & 0xf];
        }
        return new String(hashcode);
    }
    
}

 

4.新建/WEB-INF/spring/spring-service.xml(用来导出hessian服务):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
    xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/tx      http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/util    http://www.springframework.org/schema/util/spring-util-3.2.xsd
        http://www.springframework.org/schema/task    http://www.springframework.org/schema/task/spring-task-3.2.xsd
        http://www.springframework.org/schema/mvc     http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/cache  
        http://www.springframework.org/schema/cache/spring-cache-3.2.xsd">

    <context:annotation-config />
    <context:component-scan base-package="com.lichmama.demo.hessian" />
    
    <bean name="/lichService"
            class="com.lichmama.demo.hessian.exporter.AuthHessianServiceExporter">
        <property name="service" ref="hessianServiceImpl" />
        <property name="serviceInterface" value="com.lichmama.demo.hessian.service.LichService" />
    </bean>
</beans>

5.发布HessianDemo工程即可。

 

6.测试Hessian服务是否可用:1.身份验证是否可用 2.接口服务是否可用(正确返回我们期望的值)

*同样还是用spring测试,至于用DynamicWeb工程还是JavaApplication随意。

6.1新建AuthHessianProxyFactory类,用于完成客户端向服务端投递authorization完成鉴权:

AuthHessianProxyFactory:

package com.lichmama.demo.hessian.proxy;

import com.caucho.hessian.client.HessianProxyFactory;

public class AuthHessianProxyFactory extends HessianProxyFactory
{
    private final static String authorization = "1234567890";
    
    @Override
    public String getBasicAuth()
    {
        return authorization;
    }
}

测试客户端的spring-client-service.xml:

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 
     <bean id="proxyFactory" class="com.lichmama.demo.hessian.proxy.AuthHessianProxyFactory" />
 
    <bean id="lichService" 
            class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
        <property name="serviceUrl" value="http://192.168.0.152:8080/HessianDemo/lichService" />
        <property name="serviceInterface" value="com.lichmama.demo.hessian.service.LichService" />
        <property name="proxyFactory" ref="proxyFactory" />
    </bean>
  
</beans>

主要测试代码:

public class TestCase
{
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-service.xml");
        LichService service = (LichService) ctx.getBean("lichService");
        System.out.println(service.sayHello("jaychou"));
    }
    
}

正常返回:hello, jaychou

PS:修改AuthHessianProxyFactory的authorization应该拒绝你访问了(鉴权失败)。

posted @ 2016-06-08 17:31  lichmama  阅读(2479)  评论(0编辑  收藏  举报