zoukankan      html  css  js  c++  java
  • JAVA和.NET互调用

    通过接口实现JAVA和.NET互调用-JNInterface

    使用C#编程多年,也十分感激微软在语言架构、语法糖、编辑器等方面给自己带来的便利。但因为最近工作中有接触到JAVA,渐渐地发现的确像大家说的那样,JAVA的生态很好,要找点什么几乎都有现成的,于是自然就想到了能不能用.NET来调用JAVA。

    具了解,有个JNBridge的软件,可以"Bridge any Java with any .NET, anywhere",也许很好用,但是付费的,不喜欢。

    又了解了一下其他的方法,都不怎么通用,支持不健全。

    当然,通过WebService肯定是可以的,但是一直不喜欢webservice的臃肿。

    于是就自己写了一个轻量级的小组件,java和.net各一个本版,都包含一个客户端和服务端,两个本版的客户端都可以与两个本版的服务端通信。

    一句话概括来说就是:服务端监听客户端的请求,收到请求后会找到事先注册好的处理程序,处理后再返回客户端。(如果这个过程不了解,那么说明尊驾对HTTP也不了解,这段时间总有web开发者对我说http是有状态的,这一部分人应该也不理解...)

    流程是很简单的,第一步就是定义消息体了,可以理解为HTTP协议定义的消息体,HTTP里有请求和应答,这里自然也有两个相似的东西,和实际生活中好多例子一样,比如有人问你"你吃饭了吗?",出于礼貌,不管你吃了没吃,当时心情如何,都应该回复人家。

    这里我定义JNInvokeMessage和JNReturnMessage两个消息类(为了看起来清晰,贴出C#简化代码,java的基本是一样的)

    JNInvokeMessage.cs

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    public class JNInvokeMessage
    {
        public string targetName { getset; }
     
        public Dictionary<stringobject> parameters;
     
        public JNInvokeMessage(string targetName)
        {
            this.targetName = targetName;
        }
     
        public JNInvokeMessage setParam(string key, object value)
        {
            lock (this)
            {
                if (parameters == null) parameters = new Dictionary<stringobject>();
            }
            parameters[key] = value;
            return this;
        }
     
        public object getParam(string key)
        {
            if (parameters == nullreturn null;
            object obj;
            if (parameters.TryGetValue(key, out obj))
            {
                return obj;
            }
            return null;
        }
    }

     JNReturnMessage.cs

    1
    2
    3
    4
    5
    6
    7
    8
    public class JNReturnMessage
    {
        public bool ok { getset; }
     
        public string error { getset; }
     
        public object value { getset; }
    }

    下一步就是定义一个接口契约了,在C#里,可以定义一个委托:

    1
    public delegate JNReturnMessage IJNInterface(JNInvokeMessage invokeMessage);  

    java里,没有委托,所以我们定义一个接口:

    1
    2
    3
    public interface IJNInterface {
        JNReturnMessage invoke(JNInvokeMessage invokeMessage);
    }

    都是大同小异的东西,.NET委托其实是类。

    接下来就是实现Client和Server了,基本都是一些通信逻辑,老套路了网上都有,就不帖代码了,主要就是Server里有个interfaces,来保存接口处理程序,处理程序相等于MVC的Controller里的Action。在.net里用Dictionary,java里用map:

    1
    private Dictionary<string, IJNInterface> interfaces = new Dictionary<string, IJNInterface>();
    1
    private Map<String, IJNInterface> interfaces = new HashMap<String, IJNInterface>();

     字典的key就相当于url,唯一确定要调用的处理程序。 

    两边开启服务和客户端调用写法基本都是一样的,下面展示java开启服务,在.net客户端调用:

    java service 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    static void startServer() throws IOException {
        JNServer server = new JNServer();
     
        server.addInterface("test", invokeMessage -> {
            System.out.println(invokeMessage.toJson());
            JNReturnMessage returnMessage = new JNReturnMessage(true"hello .net");
            return returnMessage;
        });
        server.addInterface("home/index"new IJNInterface() {
            @Override
            public JNReturnMessage invoke(JNInvokeMessage invokeMessage) {
     
                System.out.println(invokeMessage.toJson());
                JNReturnMessage returnMessage = new JNReturnMessage(truenew int[]{12345});
     
                return returnMessage;
            }
        });
        server.start();
    }

    .net Client:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    static void Main(string[] args)
    {
        //new Thread(new ThreadStart(startServer)).Start();
        //Thread.Sleep(1000);
         
        JNClient client = new JNClient();
     
        JNInvokeMessage msg = new JNInvokeMessage("test");
         
        var ret = client.Invoke(msg);
        Console.WriteLine(ret.toJson());
    }

    .net控制台显示,说明我们调用成功:

    如果调用失败,ok为false,error是错误的描述。

    把java程序或.net程序注册为服务,在windows上建议使用srvany.exe,简单好用,这里是SrvanyUI_1.0下载,下面是我测试用的java服务设置:

    程序路径就是 java.exe,启动参数就是 -jar "服务jar包的路径"

    注意: 

    消息格式是JSON,java里用了fastjson,.net里用了Newtonsoft.Json,所以如果在返回值或参数里用了复杂的对象或集合数组类的,反序列化处理应该是fastjson里的JSONObject和JSONArray,Newtonsoft.Json里的JObject和JArray。

    下载:

    JNInterface

    源码:

    http://git.oschina.net/loogn/Loogn.JNInterface.JAVA

    http://git.oschina.net/loogn/Loogn.JNInterface.NET

     

     

     

    分类: .NET

  • 相关阅读:
    8P
    8N
    8M
    8K
    jenkins在Mac系统中默认日志、配置、启动等文件的路径
    解决Jenkins报Error fetching remote repo 'origin'的办法
    selenium的Web自动化元素点击时仍需要time.sleep等待1秒的问题
    详细配置j enokis
    mac配置启动tomcat
    mac配置启动tomcat
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5679625.html
Copyright © 2011-2022 走看看