ubuntu

Ubuntu中Python与Java如何交互

小樊
35
2025-03-18 14:53:04
栏目: 编程语言

在Ubuntu系统中,Python和Java可以通过多种方式实现交互。以下是一些常见的方法:

1. 使用Jython

Jython是一个在Java虚拟机(JVM)上运行的Python实现。它允许你在Java应用程序中直接使用Python代码。

安装Jython

wget https://repo1.maven.org/maven2/org/python/jython-standalone/2.7.2/jython-standalone-2.7.2.jar

使用Jython

java -jar jython-standalone-2.7.2.jar your_script.py

2. 使用JNI(Java Native Interface)

JNI允许Java代码调用本地代码(如C/C++),而Python可以通过C扩展与JNI交互。

步骤:

  1. 编写Java代码并编译成共享库(.so文件)。
  2. 编写Python代码调用这个共享库。

示例:

Java代码(HelloWorld.java)

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello from Java!");
    }
}

编译成共享库:

javac -h . HelloWorld.java

Python代码(call_java.py)

import ctypes

# Load the shared library
lib = ctypes.CDLL('./HelloWorld.so')

# Call the Java method
lib.main([])

3. 使用HTTP API

你可以创建一个Java应用程序作为HTTP服务器,然后使用Python通过HTTP请求与Java应用程序通信。

示例:

Java(使用Spring Boot)

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class JavaApplication {
    public static void main(String[] args) {
        SpringApplication.run(JavaApplication.class, args);
    }
}

@RestController
class HelloController {
    @GetMapping("/hello")
    public String sayHello() {
        return "Hello from Java!";
    }
}

Python(使用requests库)

import requests

response = requests.get('http://localhost:8080/hello')
print(response.text)

4. 使用消息队列

你可以使用消息队列(如RabbitMQ、Kafka)在Python和Java之间传递消息。

示例:

Java(使用RabbitMQ)

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class JavaProducer {
    private final static String QUEUE_NAME = "hello";

    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {
            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
            String message = "Hello from Java!";
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
            System.out.println(" [x] Sent '" + message + "'");
        }
    }
}

Python(使用pika库)

import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

channel.queue_declare(queue='hello')

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body.decode())

channel.basic_consume(queue='hello', on_message_callback=callback, auto_ack=True)

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

5. 使用gRPC

gRPC是一个高性能、开源和通用的RPC框架,可以在Python和Java之间实现高效的通信。

步骤:

  1. 定义.proto文件。
  2. 使用protoc编译器生成Java和Python代码。
  3. 实现服务端和客户端。

示例:

proto文件(hello.proto)

syntax = "proto3";

package hello;

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}

编译生成代码:

protoc -I=. --java_out=./java --python_out=./python hello.proto

Java(实现服务端)

import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import hello.GreeterGrpc;
import hello.HelloRequest;
import hello.HelloReply;

import java.io.IOException;

public class JavaServer {
    private Server server;

    private void start() throws IOException {
        int port = 50051;
        server = ServerBuilder.forPort(port)
                .addService(new GreeterImpl())
                .build()
                .start();
        System.out.println("Server started, listening on " + port);
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.err.println("*** shutting down gRPC server since JVM is shutting down");
            JavaServer.this.stop();
            System.err.println("*** server shut down");
        }));
    }

    private void stop() {
        if (server != null) {
            server.shutdown();
        }
    }

    private void blockUntilShutdown() throws InterruptedException {
        if (server != null) {
            server.awaitTermination();
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        final JavaServer server = new JavaServer();
        server.start();
        server.blockUntilShutdown();
    }

    static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
        @Override
        public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
            HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
            responseObserver.onNext(reply);
            responseObserver.onCompleted();
        }
    }
}

Python(实现客户端)

import grpc
import hello_pb2
import hello_pb2_grpc

def run():
    with grpc.insecure_channel('localhost:50051') as channel:
        stub = hello_pb2_grpc.GreeterStub(channel)
        response = stub.SayHello(hello_pb2.HelloRequest(name='Python'))
        print("Greeter client received: " + response.message)

if __name__ == '__main__':
    run()

选择哪种方法取决于你的具体需求和应用场景。HTTP API和消息队列适用于松耦合的系统,而JNI和gRPC适用于需要高性能和强类型检查的场景。

0
看了该问题的人还看了