python_jpype1 调用java代码

python 调用 java代码有多种方式,暂且说一下使用jpype类库进行python对java代码的使用

一. 环境配置

S1:先查看当前电脑python的版本,我的是python  64位

S2: 安装 Jpype1 类库

       我本地pip install  jpype1 的时候报错,所以本次通过下载 jpype1的离线安装包进行安装

       jpype1下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#jpype

      下载成功之后pip进行安装:pip install  JPype1‑1.0.2‑cp37‑cp37m‑win32-amd64.whl

       备注:1.选择与自己python相匹配的进行下载

                (比如:我的python是37就选择cp37,命名中带有amd64是适应python64位的,没有amd64的是适应python32位的,所以下载:JPype1‑1.0.2‑cp37‑cp37m‑win32-amd64.whl )

                  2.如果安装失败,请先安装wheel,才能安装whl离心安装包:pip install wheel

S3: java的jre虚拟环境

      python运行java代码,需要启用java的jre虚拟环境,这个jre虚拟环境依赖于 jvm.dll。所以我们需要拿到jvm.dll的路径用于后续的python代码。

      第一种情况:如果本地安装了jdk,并且版本也是64位,也设置了java_home 的环境变量,这一步可以直接跳过。

      第二种情况:下载 jre,找到相关的jvm.dll 路径。

       jre下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html

       备注:安装jre 要与python版本位数保持一致

S4: 准备java的 jar包:编写java项目,发版生成 jar包。比如:pythonCall.jar

二. 代码实现

def demo():
    '''
    python 调用 java代码的demo
    '''
    # 获取环境变量的jvm.dll 路径,
    # 从下载的jre中获取jvm.dll:jvmPath  = C:\a_Python\AAA\calljavaproject\jre\XX\jvm.dll
    jvmPath = jpype.getDefaultJVMPath()
    # 启动java的jvm虚拟环境
    jpype.startJVM(jvmPath)
    # 模拟java的代码,打印 字符串
    jpype.java.lang.System.out.println("hello world!")
    # 关闭java虚拟环境
    jpype.shutdownJVM()

因为我代码多出的case用到java的加密,所以多次调用的时候报错:JVM is already started 或者 JVM cannot be restarted,所以修改代码如下:

def start_jvm(self, sysname=""):
    try:

        # 如果 jvm环境已经启动,则直接返回成功;如没有启动,则进入else,开启java的虚拟环境
        if jpype.isJVMStarted():
            return True
        else:
            # 启动java的jvm
            # S1: 加载 java的jar包(java程序的打包)
            jarpath = os.path.join(JAVA_JAR_PATH, "pythonCall.jar")
            # S2: 开启 jvm 虚拟环境
            jpype.startJVM(self.jvmpath, "-Djava.class.path=" + jarpath)
            return True

    except Exception as e:
        log.error(sysname + "系统启动java的jvm虚拟环境出现错误,错误原因:" + str(e))
        return False

具体代码如下:

import os
import jpype

from common.util.logHelper import log



class CallJava():
    def __init__(self):
        # 获取 jvm.dll 路径:使用环境变量
        self.jvmpath = jpype.getDefaultJVMPath()

    def start_jvm(self, sysname=""):
        try:
            # 如果已经启动jvm的虚拟环境则跳过;否则进入else,启动java的虚拟环境
            if jpype.isJVMStarted():
                return True
            else:
                # 启动java的jvm
                # S1: 加载 java的jar包(java程序的打包)
                jarpath = os.path.join(JAVA_JAR_PATH, "pythonCall.jar")
                # S2: 开启 jvm 虚拟环境
                jpype.startJVM(self.jvmpath, "-Djava.class.path=" + jarpath)
                return True

        except Exception as e:
            log.error(sysname + "系统启动java的jvm虚拟环境出现错误,错误原因:" + str(e))
            return False

    def java_encrypt(self, sysname, body, keys):
        """
        加密方法: des(key).encrypt("system=sysname(系统名),time=body(当前时间)")

        注意:调用java方法,由于我写的是静态方法,直接使用类名就可以调用方法;
        如果不是静态,需要先初始化类,在调用类方法。
        sysname: "系统名"
        body:"待加密内容"
        keys:"密钥"
        """
        response = ""
        try:
            if self.start_jvm(sysname):
                # S3: 加载 java 内相关的类文件(参数是java内的长类名)
                javaclass = jpype.JClass("com.pythoncalljava.JavaClass")

                # 加密方法:javaClass.encrypt("系统名", "明文", "密钥")
                response = str(javaclass.encrypt(sysname, body, keys))

        except Exception as e:
            log.error(sysname + "系统调用java加密方法出错,错误原因:" + str(e))

        return response

    def java_encrypt_accesssecret(self, sysname, body, accesssecret, key):
        """
        加密方法: 加密后的内容 = des(key).encrypt(system=sysname,time=body,accessSecret=accessSecret)
        sysname: "系统名"
        body:"待加密内容"
        keys:"密钥"
        accesssecret: "访问密码"
        """
        response = ""
        try:
            if self.start_jvm(sysname):
                javaclass = jpype.JClass("com.pythoncalljava.SignJavaClass")
                response = str(javaclass.encrypt(sysname, body, accesssecret, key))
        except Exception as e:
            log.error(sysname + "系统调用java加密方法出错,错误原因:" + str(e))

        return response

    def java_decrypt(self, sysname, keys, encrypt_body):
        """
        解密: des(秘钥).decrypt(encrypt_body(加密的报文))
        keys:"密钥"
        encrypt_body:"加密内容"
        """
        response = ""
        try:
            if self.start_jvm(sysname):
                javaclass = jpype.JClass("com.pythoncalljava.JavaClass")
                #  解密方法:javaClass.decrypt("密钥","加密内容")
                response = javaclass.decrypt(keys, encrypt_body)
        except Exception as e:
            log.error(sysname + "系统调用java解密方法出错,错误原因:" + str(e))

        return response

    def java_decrypt_accesssecret(self, sysname, keys, encrypt_body):
        """
        解密: des(秘钥).decrypt(encrypt_body(加密的报文))
        keys:"密钥"
        encrypt_body:"加密内容"
        """
        response = ""
        try:
            if self.start_jvm(sysname):
                javaclass = jpype.JClass("com.pythoncalljava.SignJavaClass")
                #  解密方法:javaClass.decrypt("密钥","加密内容")
                response = javaclass.decrypt(keys, encrypt_body)
        except Exception as e:
            log.error(sysname + "系统调用java解密方法出错,错误原因:" + str(e))

        return response

    def shutdown_java_jvm(self):
        """
        关闭java虚拟环境
        """
        try:
            if self.start_jvm():
                jpype.shutdownJVM()
        except Exception as e:
            log.error("关闭java的jvm虚拟环境出错,错误原因:" + str(e))
            return False

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值