[转] IOS 使用KBMMW 访问JAVA 服务
废话少说,如何使用KBMMW 做个过渡,使IOS 可以使用JAVA 的服务?
其实KBMMW 本身就要java service 的服务,但是为了把这个问题说清楚,我手工做一个例子。
首先,要使用JAVA 服务,JRE 是肯定要安装的。没有安装的话,自己去java.sun.com 去下载。
安装完毕, 命令行上运行 JAVA ,出现下图说明安装成功。
在服务器上首先祭起来JVM(JAVA 虚拟机)
function GetDllName: string;var Registry: TRegistry; Version: string;begin Result := 'jvm.dll'; Registry := TRegistry.Create(KEY_READ); try Registry.RootKey := HKEY_LOCAL_MACHINE; if Registry.OpenKey('\SOFTWARE\JavaSoft\Java Runtime Environment', False) then begin Version := Registry.ReadString('CurrentVersion'); if Version <> '' then if Registry.OpenKey(Version, False) then Result := Registry.ReadString('RuntimeLib'); end; finally Registry.Free; end;end;procedure TForm1.Button3Click(Sender: TObject);var I: Integer; WebResult,WebMessage: String; n,e:integer; VM_args:JavaVMInitArgs; Options:array[0..20] of JavaVMOption; Methods:array [0..0] of JNINativeMethod; OptCnt:integer; j_MainClass:JClass; LibraryFileName:string; Mid: JMethodID; FObj,tmpobj: JObject; FInit : JMethodID; mypath:string; myclasspath:ansistring; Env:PJNIEnv; JNIEnv:TJNIEnv;const classpath='.;'; JIT=True;begin if G_javavm<>nil then begin meminfo.Lines.Add('JVM already created !'); exit; end; n:=JNI_VERSION_1_4; LibraryFileName:= GetDllName; FillChar(Options,SizeOf(Options),#0); OptCnt:=0; mypath := g_RootPath; myclasspath:=classpath+mypath+'ws\ws.jar'; Options[OptCnt].optionString:=PAnsiChar('-Djava.class.path='+ myclasspath); inc(OptCnt); if not JIT then begin Options[OptCnt].optionString:=PAnsiChar('-Djava.compiler=NONE'); inc(OptCnt); end; VM_args.version:=n; VM_args.options:= @Options ;//:= @Options; VM_args.nOptions:=OptCnt; VM_args.ignoreUnrecognized:=1; g_JavaVM := TJavaVM.Create(n, LibraryFileName); e := G_JavaVM.LoadVM(VM_args); if e<0 then begin meminfo.Lines.Add ('Error loading JavaVM via JNI 1.4+. ErrorCode='+inttostr(e)); exit; end; g_JNIEnv := TJNIEnv.Create(g_JavaVM.Env); meminfo.Lines.Add('JVM create ok!');end;
当然了,文件里面必须引用 JNI 单元。这个是kbmmw 自带的(此文件原来是JEDI 翻译jni.h 得,后来kbmmw 作者修改了,可以在新版delphi 中编译);
安装完虚拟机,就可以在delphi 中使用java 的class 了
下面就是一个简单的封装java 中hashmap 的例子
1 Thashmap = class 2 private 3 FJNIEnv: TJNIEnv; 4 FCls: JClass; 5 FObj: JObject; 6 FInit: JMethodID; 7 FPut: JMethodID; 8 FGet: JMethodID; 9 public10 constructor Create(JNIEnv:TJNIEnv;createobj:boolean=True);11 procedure put(ID,Text: string);12 Function get(ID: string):string;13 property hashmap: jobject read FObj write FObj;14 end;15 { Thashmap }16 17 constructor Thashmap.Create(JNIEnv: TJNIEnv; createobj: boolean);18 begin19 inherited Create;20 FJNIEnv:=JNIEnv;21 if FJNIEnv=nil then22 raise Exception.Create('Please create JNIEnv');23 24 FCls := FJNIEnv.FindClass('java/util/HashMap');25 if FCls=nil then26 raise Exception.Create('can''t find class HashMap');27 28 FInit := FJNIEnv.GetMethodID(FCls, '<init>', '()V');29 if FInit=nil then30 raise Exception.Create('can''t find init in class HashMap');31 32 Fput := FJNIEnv.GetMethodID(FCls, 'put', '(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;');33 34 if Fput=nil then35 raise Exception.Create('can''t find put in class HashMap');36 37 Fget := FJNIEnv.GetMethodID(FCls, 'get', '(Ljava/lang/Object;)Ljava/lang/Object;');38 39 if Fget=nil then40 raise Exception.Create('can''t find get in class HashMap');41 42 if createobj then43 begin44 FObj :=FJNIEnv.NewObjectA(FCls, FInit, nil);45 46 if Fobj=nil then47 raise Exception.Create('can''t create a HashMap');48 end;49 end;50 51 function Thashmap.get(ID: string): string;52 var53 rets:Jstring;54 begin55 rets:=FJNIEnv.CallObjectMethod( FObj,Fget,[FJNIEnv.StringToJString(id)]) ;56 57 result:=FJNIEnv.JStringToString(rets);58 end;59 60 procedure Thashmap.put(ID, Text: string);61 begin62 FJNIEnv.CallObjectMethod( FObj,Fput,[FJNIEnv.StringToJString(id),FJNIEnv.StringToJString(text)]);63 end;
这样你就可以在delphi 中使用hashmap 了。
if myhashmap<>nil then begin memo1.Lines.Add('hashmap already create!!') ; exit; end; myhashmap :=Thashmap.Create(JNIEnv); memo1.Lines.Add('HashMap create ok!!'); myhashmap.put('ROW_ID', ROW_ID); myhashmap.put('BILL_ID', BILL_ID); myhashmap.put('AUDIT_NODE', AUDIT_NODE); myhashmap.put('AUDIT_STATUS', AUDIT_STATUS); memo1.Lines.Add('put all data into hashmap'); memo1.Lines.Add('ROW_ID:'+ myhashmap.get('ROW_ID')); memo1.Lines.Add('FLOW_ID:'+ myhashmap.get('FLOW_ID'));
那么由于kbmmw 是服务器端,肯定要考虑到多线程问题。
那么要在kbmmw servive 里面调用java 服务就要稍微处理一下。
示例如下:
function Tmysrv.JavaHashMapCheck(ClientIdent: TkbmMWClientIdentity; const Args: array of Variant): Variant;var I: Integer; ROW_ID,BILL_ID: String; WebResult,WebMessage: String; n,e:integer; FObj,tmpobj, errorString: JObject; rets:Jstring; myhashmap:Thashmap; Env:PJNIEnv; JNIEnv:TJNIEnv; throwable:JThrowable; throwableClass:JClass;begin Result := ''; ROW_ID := Args[0]; BILL_ID := Args[1]; G_JavaVM.JavaVM^.AttachCurrentThread(G_JavaVM.JavaVM,@Env,nil); try JNIEnv:=TJNIEnv.Create(Env); if myhashmap<>nil then begin Result := '0'; exit; end; myhashmap :=Thashmap.Create(JNIEnv); myhashmap.put('ROW_ID', ROW_ID); myhashmap.put('BILL_ID', BILL_ID); result:='return='+myhashmap.get('ROW_ID'); throwable:=JNIEnv.ExceptionOccurred(); if throwable<>nil then begin try JNIEnv.ExceptionDescribe; throwableClass:=JNIEnv.GetObjectClass(throwable); if throwableClass<>nil then begin mid:=JNIEnv.GetMethodID(throwableClass,'toString','()Ljava/lang/String;'); if mid<>nil then begin errorString:=JNIEnv.CallObjectMethod(throwable,mid,[]); if errorString<>nil then kbmMWRaiseException(KBMMW_ERR_SERVICE_JAVA_EXCEPTION,string(JNIEnv.JStringToString(errorString))); end; end; finally JNIEnv.ExceptionClear; end; end; finally myhashmap.Free; myhashmap := nil; tmphashmap.Free; tmphashmap := nil; myObjectUtil.Free; myObjectUtil := nil; JNIEnv.Free; G_JavaVM.JavaVM^.DetachCurrentThread(G_JavaVM.JavaVM); end;end;
剩下的就是你自己处理了。
ios 里面按照老规矩调用kbmmw 服务就行了。
浙公网安备 33010602011771号