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

时间: 2024-10-01 12:20:16

JAVA和.NET互调用的相关文章

java native interface JNI 调用Java方法

在上一篇文章中介绍了JNI,以及java调用JNI,这篇讲一下 JNI调用java方法. 通过使用合适的JNI函数,你可以创建Java对象,get.set 静态(static)和 实例(instance)的域,调用静态(static)和实例(instance)函数.JNI通过ID识别域和方法,一个域或方法的ID是任何处理域和方法的函数的必须参数. 下表列出了用以得到静态(static)和实例(instance)的域与方法的JNI函数.每个函数接受(作为参数)域或方法的类,它们的名称,符号和它们对

java多线程下如何调用一个共同的内存单元(调用同一个对象)

1 /* 2 * 关于线程下共享相同的内存单元(包括代码与数据) 3 * ,并利用这些共享单元来实现数据交换,实时通信与必要的同步操作. 4 * 对于Thread(Runnable target)构造方法创建的线程,轮到它来享用CPU资源时. 5 * 目标对象就会自动调用接口中的run()方法 6 * */ 7 8 /* ----------------举例子------------------- */ 9 10 /* 11 * 使用Thread类创建两个模拟猫和狗的线程,猫和狗共享房屋中的一桶

java几种远程服务调用协议的比较

原文地址:http://www.cnblogs.com/jifeng/archive/2011/07/20/2111183.html 一.综述 本文比较了RMI,Hessian,Burlap,Httpinvoker,web service等5种通讯协议的在不同的数据结构和不同数据量时的传输性能. RMI是java语言本身提供的远程通讯协议,稳定高效,是EJB的基础.但它只能用于JAVA程序之间的通讯. Hessian和Burlap是caucho公司提供的开源协议,基于HTTP传输,服务端不用开防

c++与java中子类中调用父类成员的方法

1 java中: 2 import java.util.Scanner; 3 public class ClassTest{ 4 public static void main(String args[]){ 5 child ch=new child(2); 6 parent p=ch; 7 p.print(); 8 //p.print2();//调用错误,父类中没有改成员方法,该方法只属于子类! 9 } 10 } 11 12 class parent{ 13 int xx; 14 parent

JNI实现JAVA和C++互相调用

SDK.h 1 #ifndef SDK_H 2 #define SDK_H 3 4 #include "AsyncProxy.h" 5 #include "Module.h" 6 #include <map> 7 #include <vector> 8 #include <string> 9 using std::map; 10 using std::vector; 11 using std::string; 12 13 14 c

JAXB完成XML与Java对象的互转

这段时间都老忙了,甚至连周末所有人员都在赶产品的进度,想想连续上12天班,人都有点晕了!到这会儿终于有点时间,所以准备和大家分享一下JAXB,会不会有人觉得有点陌生呢?没事,这里跟大伙儿简单的描述一下: JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术.该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档.从另一方面来讲,JA

java之如何实现调用启动一个可执行文件,exe

1 /* 2 * 运行可执行文件:.exe 3 * 当要执行一个本地机器上的可执行文件时, 4 * 可以使用java.lang包中的Runtime类,首先使用Runtime类,首先 5 * 使用Runtime类声明一个对象 6 *{ 7 * Runtime sc =Runtime.getRuntime(); 8 * sc可以调用exec(String command) 方法打开本地湖区上的可执行文件或执行一个操作. 9 * } 10 */ 11 12 13 /* 14 * 不妨举列: 15 *

java和bat相互调用

1.bat 启动java main函数 1.将project导出JAR,过程中注意选择main class 2.新建bat,设置环境变量 3.1启动程序,如果想在黑窗口中打印数字,可以system.out,程序运行万 @echo off @setlocal set JAVA_HOME=jdk1.6.0_25 set PATH=%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin java -jar start.jar 或者直接调用class文件 @echo off @setlo

C++、C#互调用之C++ 调用C# dll (转载)

1.c# 创建dll 建立C#编写的DLL程序AddDll,项目类型为:类库 程序代码: using System; using System.Collections.Generic; using System.Text; namespace AddDll { public class Add { public int iadd(int a, int b) { int c = a + b; return c; } } } 2.C++编写调用程序 建立C++的Win32控制台应用程序UseDll,