为什么需要PB调用JAVA
java使用人员众多,有丰富的生态,有各种功能的库。pb通过调用java可以极大地丰富pb的能力。比如对接国家医保时,只提供了JAVA的示例,我们通过PB调用JAVA可以极大地减少对接的工作量,快速实现对接。
通过SatJNI我们可以很容易地实现PB调用JAVA类。
PB调用JAVA的方法
我们以调用医保示例为例,说明PB调用JAVA的方法
生成ybutil.jar
创建JAVA的医保示例工程,并导入相关的示例和需要JAR,创建后如下:
说明:其中libs中是需要用到jar库,bcp和hsaf开头的是算法和加密相关的库,其它是一些帮助类HseEncAndDecUtil是示例
创建完成后可以导出jar。不熟悉java创建工程和导出jar的同学可以参考百度方法,这里不是调用重点就不详细说明。
PB代码
我们以调用main方法中的
SM2Util.getKeyPairStr()
为例,PB调用过程如下:
1. 首先我们下载SatJNI,里面包含了示例代码
主要函数定义在n_jvmapi中,n_jvmapi代码如下
forward
global type n_jvmapi from nonvisualobject
end type
end forward
global type n_jvmapi from nonvisualobject autoinstantiate
end type
type prototypes
Function ulong SatJVM_Create(String jarPath) library "satjni.dll"
Subroutine SatJVM_Destroy(ulong jvm) library "satjni.dll"
function Any SatJVM_Invoke(ulong jvm, ulong code, ...) system library "satjni.dll" alias for "SatJVM_Invoke"
end prototypes
type variables
//JVM
constant ulong API_InvokeStaticMethod = 2
constant ulong API_InvokeObjectMethod = 3
constant ulong API_CreateInstance = 4
constant ulong API_DestroyInstance = 5
constant ulong API_SetStaticField = 6
constant ulong API_SetObjectField = 7
constant ulong API_GetStaticField = 8
constant ulong API_GetObjectField = 9
end variables
on n_jvmapi.create
call super::create
TriggerEvent( this, "constructor" )
end on
on n_jvmapi.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on
2. 在程序open事件中初始化satjni并加载JAVA的jar或者class类的根文件夹
gl_jvm = n_api.SatJVM_Create("java;ybutil.jar")
其中java表示加载当前目录下面的java文件夹的代码,ybutil.jar是封装的医保的java库,多个文件夹或库以 ;号分隔
3. 通过 SatJVM_Invoke 调用JAVA的方法
调用静态方法(如调用医保的sm2生成公钥和私钥,该方法在示例中):
Any l,r
Exception lexp
l = n_api.SatJVM_Invoke(gl_jvm,n_api.API_InvokeStaticMethod,"cn.hsaf.common.algorithm.sm2.SM2Util","getKeyPairStr")
if classname(l) = "exception" then
lexp = l
messagebox("出错",lexp.Text)
end if
r = n_api.SatJVM_Invoke(gl_jvm,n_api.API_invokeobjectmethod,l,"toString")
messagebox("结果:"+ classname(l),string(r))
调用类实例的方法(如实例化fastjson的JSONObject对象,并调用方法):
Any l,r,jsonObj
Exception lexp
jsonObj = n_api.SatJVM_Invoke(gl_jvm,n_api.API_CreateInstance,"com.alibaba.fastjson.JSONObject")
n_api.SatJVM_Invoke(gl_jvm,n_api.API_invokeobjectmethod,jsonObj,"put","appUserId","ohNH9sgKsmJC3tR_spm9jcQx_bh")
n_api.SatJVM_Invoke(gl_jvm,n_api.API_invokeobjectmethod,jsonObj,"put","appId","ohNH9sgKsmJC3tR_spm9jcQx_bh")
n_api.SatJVM_Invoke(gl_jvm,n_api.API_invokeobjectmethod,jsonObj,"put","idNo","ohNH9sgKsmJC3tR_spm9jcQx_bh")
n_api.SatJVM_Invoke(gl_jvm,n_api.API_invokeobjectmethod,jsonObj,"put","idType","01")
n_api.SatJVM_Invoke(gl_jvm,n_api.API_invokeobjectmethod,jsonObj,"put","userName","ccccccc")
n_api.SatJVM_Invoke(gl_jvm,n_api.API_invokeobjectmethod,jsonObj,"put","authCode","11111")
r = n_api.SatJVM_Invoke(gl_jvm,n_api.API_invokeobjectmethod,jsonObj,"toString")
messagebox("结果:"+ classname(l),string(r))
4. PB效果如下:
医保文档中JAVA示例调用
1. 加密解密示例(java)
代码中EasyGmUtils类为工具包中EasyGmUtils.java
package com.neusoft.common.core.utils.bcutil;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Demo {
//sm4加密解密
public void encrypt(){
String clientid="A761C400E3C6A0E8";
String plainString = "12345";
byte[] plain = plainString.getBytes();
System.out.println("明文------>"+new String(plain));
byte[] bs = EasyGmUtils.sm4Encrypt(clientid.getBytes(StandardCharsets.UTF_8), plain);
String mi=new String(Base64.getEncoder().encode(bs));
System.out.println("加密后-------->"+mi);
bs = EasyGmUtils.sm4Decrypt(clientid.getBytes(StandardCharsets.UTF_8), Base64.getDecoder().decode(mi));
System.out.println("解密后------->"+new String(bs));
}
}
转为pb代码
Any l,r
Exception lexp
String clientid,plainString,ls_data
blob lb_1,lb_2
blob lb_b
ulong ll_len
clientid="A761C400E3C6A0E8";
plainString = "12345";
//加密
lb_1 = n_util.of_toutf8(clientid)
lb_2 = n_util.of_toutf8( plainString)
lb_b = n_api.SatJVM_Invoke(gl_jvm,n_api.API_InvokeStaticMethod,"cn.hsaf.common.utils.EasyGmUtils","sm4Encrypt",lb_1,lb_2)
ls_data = n_util.of_base64encode(lb_b)
messagebox("加密后-------->",ls_data)
//解密
lb_b = n_util.of_base64decode(ls_data)
lb_b = n_api.SatJVM_Invoke(gl_jvm,n_api.API_InvokeStaticMethod,"cn.hsaf.common.utils.EasyGmUtils","sm4Decrypt",lb_1,lb_b)
ls_data = n_util.of_utf8tostring(lb_b)
messagebox("解密后------->",ls_data)
2. 签名验签示例
签名验签,代码中EasyGmUtils类为工具包中EasyGmUtils.java
package com.neusoft.common.core.utils.bcutil;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Demo {
//sm2签名验签
public void sign(){
String clientid="A761C400E3C6A0E8";
String plainString = "12345";
byte[] prvkey = Base64.getDecoder().decode("Z4SyKZTW5ebDFfYvEkkbMvmCWwkDL1AkCImZ5c9XKK0=");
byte[] pubkey = Base64.getDecoder().decode("BIG/ekjsAHDMfaE+s7iaKoZhMwz1ON29hvXyKc8XF35lAaWgJh4CA02YUpg5X0B4EG6DsFOiVDhAtRkC/iVkTbs=");
byte[] asig = EasyGmUtils.signSm3WithSm2(plainString.getBytes(StandardCharsets.UTF_8), clientid.getBytes(StandardCharsets.UTF_8), prvkey);
String signstr=new String(Base64.getEncoder().encode(asig));
System.out.println("签名串str---->"+signstr);
boolean verified = EasyGmUtils.verifySm3WithSm2(plainString.getBytes(StandardCharsets.UTF_8), clientid.getBytes(StandardCharsets.UTF_8), Base64.getDecoder().decode(signstr), pubkey);
System.out.println("签名校验---->"+verified);
}
}
转为pb代码
Any l,r
Exception lexp
String clientid,plainString,ls_data,signstr
blob lb_prvkey,lb_pubkey,asig
blob lb_plain,lb_clientid
ulong ll_len
boolean verified
clientid="A761C400E3C6A0E8";
plainString = "12345";
lb_clientid = n_util.of_toutf8( clientid)
lb_plain = n_util.of_toutf8( plainString)
lb_prvkey = n_util.of_base64decode( "Z4SyKZTW5ebDFfYvEkkbMvmCWwkDL1AkCImZ5c9XKK0=")
lb_pubkey = n_util.of_base64decode( "BIG/ekjsAHDMfaE+s7iaKoZhMwz1ON29hvXyKc8XF35lAaWgJh4CA02YUpg5X0B4EG6DsFOiVDhAtRkC/iVkTbs=")
asig = n_api.SatJVM_Invoke(gl_jvm,n_api.API_InvokeStaticMethod,"cn.hsaf.common.utils.EasyGmUtils","signSm3WithSm2", &
lb_plain ,lb_clientid,lb_prvkey)
signstr = n_util.of_base64encode(asig)
messagebox("签名串str---->",signstr)
asig = n_util.of_base64decode(signstr)
verified = n_api.SatJVM_Invoke(gl_jvm,n_api.API_InvokeStaticMethod,"cn.hsaf.common.utils.EasyGmUtils",&
"verifySm3WithSm2", lb_plain ,lb_clientid,asig, lb_pubkey)
messagebox("签名校验---->",verified)
有问题可以咨询QQ:9091178