JSON-RPC是一个无状态且轻量级的远程过程调用(RPC)协议。
它主要定义了一些数据结构及其相关的处理规则。
它运行时可以基于tcp(socket),http等不同的消息传输方式,
即它不关心底层传输方式的细节。
它使用JSON(RFC 4627)作为数据格式。
目前版本为JSON-RPC 2.0。
JSON-RPC over HTTP是一种基于HTTP协议的传输方式实现JSON-RPC,
在客户端和服务器之间传输JSON-RPC定义的JSON格式的数据。
本文通过jsonrpc4j实现JSON-RPC,
通过Spring Boot对外提供HTTP接口,
两种相结合可以实现JSON-RPC over HTTP。
服务端对外提供HTTP接口的方式有很多,
这里选择集成常用的Spring Boot框架。
新建父工程JSON-RPC-SpringBoot,
pom增加依赖管理如下:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>2.3.1.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>com.github.briandilley.jsonrpc4jgroupId>
<artifactId>jsonrpc4jartifactId>
<version>1.6version>
dependency>
dependencies>
dependencyManagement>
新建子工程JSON-RPC-SB-api,
该工程用于在服务端和客户端共享RPC API,
只依赖jsonrpc4j开源框架,
pom增加依赖如下:
<dependencies>
<dependency>
<groupId>com.github.briandilley.jsonrpc4jgroupId>
<artifactId>jsonrpc4jartifactId>
dependency>
dependencies>
创建对外的JSON-RPC接口BookRpcService.java:
package com.ai.json.rpc.service;
import com.ai.json.rpc.entity.Book;
import com.googlecode.jsonrpc4j.JsonRpcService;
@JsonRpcService("rpc/books")
public interface BookRpcService {
public Book findById(String id);
}
创建用到的实体类Book.java
package com.ai.json.rpc.entity;
public class Book {
private String id;
private String name;
private int price;
}
创建子工程JSON-RPC-SB-server,
pom增加依赖如下:
<dependencies>
<dependency>
<groupId>edu.yuwen.protocolgroupId>
<artifactId>JSON-RPC-SB-apiartifactId>
<version>${project.version}version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
创建服务端启动类JsonRpcClientApplication.java:
package com.ai.json.rpc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class JsonRpcApplication {
public static void main(String[] args) {
SpringApplication.run(JsonRpcApplication.class, args);
}
}
创建jsonrpc4j的配置类RpcConfiguration.java:
package com.ai.json.rpc.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImplExporter;
@Configuration
public class RpcConfiguration {
@Bean
public AutoJsonRpcServiceImplExporter rpcServiceImplExporter() {
return new AutoJsonRpcServiceImplExporter();
}
}
创建BookRpcService这个RPC接口的实现类BookRpcServiceImpl.java:
package com.ai.json.rpc.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ai.json.rpc.entity.Book;
import com.ai.json.rpc.service.BookRpcService;
import com.ai.json.rpc.service.BookService;
import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImpl;
@AutoJsonRpcServiceImpl
@Service
public class BookRpcServiceImpl implements BookRpcService {
private static Logger LOG = LoggerFactory.getLogger(BookRpcServiceImpl.class);
private static Map<String, Book> id2Book = new HashMap<>();
static {
id2Book.put("1", new Book("1", "Java核心技术", 199));
id2Book.put("2", new Book("2", "人月神话", 58));
id2Book.put("3", new Book("3", "程序员养生指南", 996));
}
@Override
public Book findById(String id) {
Book book = id2Book.get(id);
LOG.info("根据图书Id={}找到图书Book={}", id, book);
return book;
}
}
在启动JSON-RPC服务端后,
可以使用Postman调用服务端提供的接口,
因为这里面使用的HTTP和JSON技术都是基于现成的技术栈。
Postman调用设置如下:
HTTP Method: POST
HTTP URL: http://localhost:9090/rpc/books
Content-Type: application/json
请求内容:
{
"id": "2073176624",
"jsonrpc": "2.0",
"method": "findById",
"params": [
"3"
]
}
JSON-RPC API接口调用成功,
响应内容:
{
"jsonrpc": "2.0",
"id": "2073176624",
"result": {
"id": "3",
"name": "程序员养生指南",
"price": 996
}
}