资讯专栏INFORMATION COLUMN

Hessian在实际项目中的使用

shuibo / 561人阅读

摘要:项目介绍最近在一个互联网跨境支付项目组,所使用的技术比较老,代码是写于年的,整个系统采用服务的架构模式,连接件使用进行同步调用,使用进行异步调用。言归正传,本文主要是讲一下,在该项目中的使用。封装了的功能,便于调用。主要包括枚举类和帮助类。

项目介绍

最近在一个互联网跨境支付项目组,所使用的技术比较老,代码是写于2006年的,整个系统采用服务的架构模式,连接件使用hessian进行同步调用,使用MQ进行异步调用。
跨境系统的服务分类上,主要有两类,一类是线上的,比如交易,网关,出金,入金等,一类是线下的,比如对账,核算等。这个分类方法,有点像之前金融市场业务功能分成前中后台子系统。言归正传,本文主要是讲一下,hessian在该项目中的使用。

划分模块

整个工程分为两个WEB模块:客户调用模块client,服务处理模块handler。两个基本jar组件:服务注册组件register,hessian工具组件hessianutil.

register : 只有一个枚举,用于注册服务,一个服务一个枚举。是不是瞬间感觉低端了。
hessianutil : 提供了hessian操作的工具类套件。之所以将这两个分开,是因为hessianutil基本不变,而注册类就经常变动了
client : 服务调用者
handler : 服务提供者

代码 register:
public enum SerCode {
    SIMPLE_CALL_RETURN_STRING("000000","简单调用"),
    SIMPLE_CALL_RETURN_MAP("000001","返回字典");

    private String code;
    private String desc;

    SerCode(String code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public String getCode() {
        return code;
    }

    public String getDesc() {
        return desc;
    }
}
client:

注意在hessian的service中传入了handler的服务调用地址,hessian会创建代理,来实现RPC调用

public void makeSimpleCall(){
        Map paraMap = new HashMap();
        String reqMsg = JSonUtil.toJSonString(paraMap);
        HessianInvokeParam param = HessianInvokeHelper.processRequest(reqMsg);
        String sysTraceNo = SysTraceNoService
                .generateSysTraceNo(SystemCodeEnum.WEBGATE.getCode());
        String result = clientHessianService.invoke(
                SerCode.SIMPLE_CALL_RETURN_STRING.getCode(), sysTraceNo,
                SystemCodeEnum.WEBGATE.getCode(),
                SystemCodeEnum.TXNCORE.getCode(),
                SystemCodeEnum.TXNCORE.getVersion(), param.getDataLength(),
                param.getMsgCompress(), param.getDataMsg());
        param.parse(result);
        HessianInvokeHelper.processResponse(param);
        result = param.getDataMsg();
        System.out.println("result:"+result);
    }
     
        
        
    
handler:
public class SimpleHandler implements EventHandler {
    public String handle(String dataMsg) throws HessianInvokeException {
        return "this is from simple handler";
    }
}


        


    
        
            
        
    




        
        


        contextConfigLocation
        
            classpath*:context/**/*.xml
        
    
    
        org.springframework.web.context.ContextLoaderListener
    
    
        remoting
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            
                classpath*:remote/**/*.xml
            
        
    
    
        remoting
        /service/*
    

通过如上配置,客户端就可以通过访问http://localhost:8080/handler...和对应的code来访问handler了。

hessianutil

封装了hessian的功能,便于调用。里面的类就不一一做介绍了。主要包括枚举类和帮助类。

//所有handler必须实现的接口
public interface EventHandler {
    String handle(String dataMsg) throws HessianInvokeException;
}
//hessian调用时用的接口
public interface HessianInvokeService {
    /**
     * Hessian通讯服务接口
     *
     * @param serCode
     *            服务代码
     * @param sysTraceNo
     *            系统跟踪号
     * @param originNo
     *            源系统编号
     * @param targetNo
     *            目的系统编号
     * @param versionNo
     *            接口版本号 格式:1.0.0
     * @param dataLength
     *            消息正文长度
     * @param msgCompress
     *            消息正文是否压缩
     * @param dataMsg
     *            消息正文
     * @return
     */
    String invoke(String serCode, String sysTraceNo, String originNo,
                  String targetNo, String versionNo, int dataLength, int msgCompress,
                  String dataMsg);

}
//调用的主要方法类
public class HessianService implements HessianInvokeService {

    private final Log logger = LogFactory.getLog(HessianService.class);
    private Map eventHandlerMap;
    public void setEventHandlerMap(Map eventHandlerMap) {
        this.eventHandlerMap = eventHandlerMap;
    }
    @SuppressWarnings("unchecked")
    @Override
    public String invoke(String serCode, String sysTraceNo, String originNo,
                         String targetNo, String versionNo, int dataLength, int msgCompress,
                         String dataMsg) {

        logger.info("requet auth system:" + "serCode:" + serCode
                + "sysTraceNo:" + sysTraceNo + "originNo:" + originNo
                + "targetNo:" + targetNo + "versionNo:" + versionNo);

        if(logger.isDebugEnabled()){
            logger.info("dataMsg:" + dataMsg);
        }

        Map result = new HashMap();
        try {

            // 验证请求参数
            HessianInvokeHelper.validateReqParam(serCode, sysTraceNo, originNo,
                    targetNo, versionNo, dataLength, msgCompress, dataMsg);

            // 验证请求服务代码是否正确
            EventHandler handler = eventHandlerMap.get(serCode);
            if (handler == null) {
                throw new HessianInvokeException(
                        ResponseCodeEnum.UNDEFINED_SERVICE.getCode(),
                        ResponseCodeEnum.UNDEFINED_SERVICE.getDesc());
            }

            // 验证目标系统编码
            HessianInvokeHelper.validateTargetNo(targetNo,
                    SystemCodeEnum.TXNCORE.getCode());

            // 验证请求消息正文内容长度
            HessianInvokeHelper.validateDataMsgSize(dataLength, dataMsg);

            String reqMsg = dataMsg;
            // 判断是否需要解压请求消息正文内容
            if (msgCompress == 1) {
                try {
                    reqMsg = ZipUtil.uncompress(dataMsg);
                } catch (IOException e) {
                    throw new HessianInvokeException(
                            ResponseCodeEnum.UNCOMPRESS_FAILURE.getCode(),
                            ResponseCodeEnum.UNCOMPRESS_FAILURE.getDesc(), e);
                }
            }

            if(logger.isDebugEnabled()){
                logger.info("reqMsg:" + reqMsg);
            }

            Map map = JSonUtil.toObject(reqMsg, Map.class);
            map.put("sysTraceNo", sysTraceNo);
            String rsp = handler.handle(JSonUtil.toJSonString(map));

            return HessianInvokeHelper.buildResponse(serCode, sysTraceNo,
                    SystemCodeEnum.TXNCORE.getCode(), originNo, versionNo, rsp);

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            logger.error(e.getMessage(), e);
            result.put("responseCode",
                    ResponseCodeEnum.UNDEFINED_ERROR.getCode());
            result.put("responseDesc",
                    ResponseCodeEnum.UNDEFINED_ERROR.getDesc());
        }
        return HessianInvokeHelper.buildResponse(serCode, sysTraceNo,
                SystemCodeEnum.TXNCORE.getCode(), originNo, versionNo,
                JSonUtil.toJSonString(result));
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70261.html

相关文章

  • Spring Boot整合hessian入门

    摘要:相比,更简单快捷。采用的是二进制协议,因为采用的是二进制协议,所以它很适合于发送二进制数据。创建接口创建实现类类端在这个包下服务端包类将服务端的代码打包安装到本地仓库,打开浏览器输入即可。 前言 看了其他的文章发现,大多数都是只写了关键的部分,对于一个初学者来说只能明白用了什么东西,但实际动手发现,项目还存在一些问题,通过本篇文章,可以避免一些问题,节省一些时间成本。 Hessian简...

    wujl596 评论0 收藏0
  • dubbo个人理解于应用章(二)

    摘要:当提供程序线程池耗尽时,不能发送到使用者端。一些错误修正动态配置不能删除,支持参数,监控统计问题等新功能支持手册线程池耗尽时自动堆栈转储。在注册表无法连接时被阻止。正常关机,在注册表取消注册和线程池关闭之间增加额外的等待时间。 dubbo分析showImg(https://segmentfault.com/img/bVbam2f?w=1726&h=686); dubbo为什么要对接sp...

    AlphaWallet 评论0 收藏0
  • Spring Hessian调用端代码浅析

    摘要:最近公司内部系统相互通信调用用到了的机制后来有空研究了一下的机制在这里做一个简单的摘要有不对的地方希望指正首先看客户端的基础类他是一个工厂意味着他具有包装的功能当你调用的的的方法返回的并不是他本身而是被他包装过得下图的箭头及包装的地方实际上 最近公司内部系统相互通信调用用到了spring的hessian机制,后来有空研究了一下spring hessian的机制,在这里做一个简单的摘要,...

    jzman 评论0 收藏0
  • 网络协议 22 - RPC 协议(下)- 二进制类 RPC 协议

    摘要:但是只不过都是以二进制的形式编码的。这其实相当于综合了和二进制共同优势的一个协议。在上面的架构中,如果使用二进制的方式进行序列化,虽然不用协议文件来生成,但是对于接口的定义,以及传的对象,还是需要共享。     前面我们认识了两个常用文本类的 RPC 协议,对于陌生人之间的沟通,用 NBA、CBA 这样的缩略语,会使得协议约定非常不方便。     在讲 CDN 和 DNS 的时候,我们...

    付伦 评论0 收藏0
  • 网络协议 22 - RPC 协议(下)- 二进制类 RPC 协议

    摘要:但是只不过都是以二进制的形式编码的。这其实相当于综合了和二进制共同优势的一个协议。在上面的架构中,如果使用二进制的方式进行序列化,虽然不用协议文件来生成,但是对于接口的定义,以及传的对象,还是需要共享。     前面我们认识了两个常用文本类的 RPC 协议,对于陌生人之间的沟通,用 NBA、CBA 这样的缩略语,会使得协议约定非常不方便。     在讲 CDN 和 DNS 的时候,我们...

    wing324 评论0 收藏0

发表评论

0条评论

shuibo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<