• 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应该拒绝你访问了(鉴权失败)。

  • 相关阅读:
    L1-046. 整除光棍
    判断素数
    L1-025. 正整数A+B
    L1-023. 输出GPLT
    L1-020. 帅到没朋友
    L1-016. 查验身份证
    L1-011. A-B
    UVa 400 Unix Is命令
    Uva 136 丑数
    The Preliminary Contest for ICPC Asia Xuzhou 2019 K. Center
  • 原文地址:https://www.cnblogs.com/lichmama/p/5570779.html
Copyright © 2020-2023  润新知