Delphi调用Java类(支持Java 6)

来源:互联网 发布:网络信息安全攻防平台 编辑:程序博客网 时间:2024/06/06 09:02

 

       这两天正在做一个项目,需要使用Delphi与互联网社区网站进行对接,协议中使用了RSA加密;通过测试,Delphi的RSA算法无法与Java的RSA算法兼容,经过各种周折最终尝试了Delphi调用Java的类的方法进行RSA加密解密;这是非常令人振奋的解决方案,但是前期也遇到不少问题。

       在网上找到http://www.delphi-jedi.org/中的jni.pas及相关的例子,但是用的是jdk1.4的,问了对方说至少需要jdk1.5,差点放弃了该方案;通过各种尝试及网上搜索终于找到了一个支持jdk1.6的jni.pas接口源文件,一切豁然开朗,下面分享一下我的成果。

运行效果图

源代码:

unit main;interfaceuses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, uJNI, StdCtrls;type  Tfmain = class(TForm)    btnInvoking: TButton;    mmoResult: TMemo;    edtClassName: TEdit;    lblClassName: TLabel;    edtMethodName: TEdit;    lblMethodName: TLabel;    edtData: TEdit;    lblData: TLabel;    lblResult: TLabel;    btnExit: TButton;    procedure FormDestroy(Sender: TObject);    procedure btnInvokingClick(Sender: TObject);    procedure btnExitClick(Sender: TObject);    procedure FormCreate(Sender: TObject);  private    { Private declarations }    FJavaVM: TJavaVM;    FJNIEnv: TJNIEnv;    // 加载虚拟机    procedure LoadVM();    // 调用Java方法    procedure InvokingJavaMethod();  public    { Public declarations }  end;var  fmain: Tfmain;implementation{$R *.dfm}// 加载虚拟机procedure Tfmain.LoadVM;var  Errcode: Integer;  VM_args: JavaVMInitArgs;  Options: array[0..10] of JavaVMOption;begin  try    // 创建虚拟机对象,并传入jvm.DLL接口路径    FJavaVM := TJavaVM.Create(JNI_VERSION_1_6, 'jre6\bin\client\jvm.dll');    FillChar(Options, SizeOf(Options), #0);    // 设置jar包或类的搜索路径,多个jar使用分号隔开    Options[0].optionString := '-Djava.class.path=.;RSA.jar';    // 声明使用jdk1.6版本    VM_Args.version := JNI_VERSION_1_6;    VM_Args.options := @Options;    VM_Args.nOptions := 1;    VM_Args.ignoreUnrecognized := False;    // 加载虚拟机    ErrCode := FJavaVM.LoadVM(VM_Args);    if ErrCode < 0 then    begin      // Loading the VM more than once will cause this error      if Errcode = JNI_EEXIST then        MessageDlg('Java VM has already been loaded. Only one VM can be loaded.', mtError, [mbOK], 0)      else        ShowMessageFmt('Error creating JavaVM, code = %d', [Errcode]);      Exit;    end;       // Create the Env class    FJNIEnv := TJNIEnv.Create(FJavaVM.Env);          except    on E: Exception do    begin      ShowMessage('Error: ' + E.Message);      Exit;    end;  end;end;// 调用Java方法procedure Tfmain.InvokingJavaMethod;var  Cls: JClass;  Mid: JMethodID;  sResult: WideString;  JStr: JString;  sData: UTF8String;  sMethod, sClass: PAnsiChar;begin      try    // 将传入的参数值转成UTF8字符,用于支持中文    sData :=UTF8Encode(edtData.Text);    // 方法名称    sMethod := PAnsiChar(edtMethodName.Text);    // 类名称    sClass := PAnsiChar(edtClassName.Text);        // 查找类,注意:类的路径需要做转换,如:cn.com.tcsl.RSA 应转化为 cn/com/tcsl/RSA    Cls := FJNIEnv.FindClass(sClass);    if Cls = nil then    begin      ShowMessage('Can''t find class: '+sClass);      Exit;    end;    // 定位类的静态方法sMethod,并配置参数结构    Mid := FJNIEnv.GetStaticMethodID(Cls, sMethod, '(Ljava/lang/String;)Ljava/lang/String;');    if Mid = nil then    begin      ShowMessage('Can''t find method: '+sMethod);      Exit;    end;    // 调用静态方法    JStr := FJNIEnv.CallStaticObjectMethod(Cls, Mid, [sData]);    // 将JString转化成Delphi String,注意:需要使用UTF8Decode解码UTF8字符    sResult :=UTF8Decode(FJNIEnv.JStringToString(JStr));    // 显示结果    mmoResult.Lines.Add(sResult);  except    on E: Exception do      ShowMessage('Error: ' + E.Message);  end;end;procedure Tfmain.FormCreate(Sender: TObject);begin  LoadVM();end;procedure Tfmain.FormDestroy(Sender: TObject);begin  FJNIEnv.Free;  FJavaVM.Free;end;procedure Tfmain.btnInvokingClick(Sender: TObject);begin  InvokingJavaMethod();end;procedure Tfmain.btnExitClick(Sender: TObject);begin  Close;end;end.

     该例子只使用了最简单的参数模式,但是一般已经够用了(即调用一个Java类的方法,传入字符,返回处理后的字符),更复杂的用法可以参考http://www.pacifier.com/~mmead/jni/delphi/JEDI/DOCS/delphi-jni-3.html。

    为了方便大家调试我上传了完整的源码及jar6包,大家省事了,下载直接能够调试运行。

    源代码下载

 

 


原创粉丝点击