偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

再見 Feign!Spring Boot + JSON-RPC遠(yuǎn)程調(diào)用新選擇

開發(fā) 前端
目前JSON-RPC的版本是2.0,該版本是目前廣泛使用的版本,它增加了錯(cuò)誤處理、批處理請(qǐng)求(batch requests)、通知(notifications)等特性。

環(huán)境:SpringBoot3.4.2

1. 簡(jiǎn)介

什么是JSON-RPC協(xié)議?

JSON-RPC 是一種輕量級(jí)的遠(yuǎn)程過程調(diào)用(Remote Procedure Call,RPC)協(xié)議,它允許你在不同的系統(tǒng)之間通過網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)交換和調(diào)用函數(shù)。JSON-RPC 使用 JSON(JavaScript Object Notation)作為數(shù)據(jù)格式,這使得它非常適合于各種編程語言和平臺(tái)之間的通信。

目前JSON-RPC的版本是2.0,該版本是目前廣泛使用的版本,它增加了錯(cuò)誤處理、批處理請(qǐng)求(batch requests)、通知(notifications)等特性。

JSON-RPC 2.0結(jié)構(gòu)

請(qǐng)求,通常包含以下幾個(gè)字段:

  • jsonrpc: String,版本號(hào),通常為 "2.0"
  • method: String,要調(diào)用的方法的名稱
  • params: 可選,參數(shù)列表或?qū)ο?,傳遞給方法的參數(shù)
  • id: 可選,一個(gè)字符串、數(shù)字或 null。用于唯一標(biāo)識(shí)請(qǐng)求,以便響應(yīng)能夠回傳給正確

響應(yīng),通常包含以下幾個(gè)字段:

  • jsonrpc: 字符串,版本號(hào),通常為 "2.0"
  • result: 請(qǐng)求成功時(shí)的返回值
  • error: 請(qǐng)求失敗時(shí)的錯(cuò)誤對(duì)象
  • id: 與請(qǐng)求中的 ID 相匹配

說明:result與error,最終只會(huì)有一個(gè)返回。

JSON-RPC不同的編程語言都有對(duì)應(yīng)的實(shí)現(xiàn),在java中比較流行的則是jsonrpc4j,而本篇文章將基于該開源庫進(jìn)行詳細(xì)的介紹。

什么是jsonrpc4j?

jsonrpc4j 使用 Jackson 庫將 Java 對(duì)象與 JSON 對(duì)象進(jìn)行相互轉(zhuǎn)換(以及其他與 JSON-RPC 相關(guān)的功能)。包括以下功能:

  • 流式服務(wù)器(InputStream / OutputStream)
  • HTTP 服務(wù)器(HttpServletRequest / HttpServletResponse)
  • Portlet 服務(wù)器(ResourceRequest / ResourceResponse)
  • Socket 服務(wù)器(StreamServer)
  • 與 Spring 框架集成
  • 流式客戶端
  • HTTP 客戶端
  • 動(dòng)態(tài)客戶端代理
  • 注解支持
  • 自定義錯(cuò)誤解析
  • 復(fù)合服務(wù) 

2.實(shí)戰(zhàn)案例

2.1 依賴管理&接口定義

<dependency>
  <groupId>com.github.briandilley.jsonrpc4j</groupId>
  <artifactId>jsonrpc4j</artifactId>
  <version>1.7</version>
</dependency>

目前最新版本為1.7。

接口定義

public interface UserService {


  User createUser(String userName, String firstName, String password);
  User createUser(String userName, String password);
  User findUserByUserName(String userName);
  int getUserCount();
}
// 接口實(shí)現(xiàn)
@Service
@Primary
public class UserServiceImpl implements UserService {
  private static final List<User> USERS = new ArrayList<>();
  public User createUser(String userName, String firstName, String password) {
    User user = new User(userName, firstName, password);
    USERS.add(user);
    return user;
  }
  public User createUser(String userName, String password) {
    return this.createUser(userName, null, password);
  }
  public User findUserByUserName(String userName) {
    System.err.println("admin".equals(userName) ? 1 / 0 : "success") ;
    return USERS.stream().filter(user -> user.userName().equals(userName)).findFirst().orElse(null);
  }
  public int getUserCount() {
    return USERS.size();
  }
}

接下來,我們將從以下方面對(duì) jsonrpc4j 進(jìn)行詳細(xì)說明與使用示例解析。

  • RPC Server接口暴露的2種方式
  • RPC Client調(diào)用的3種方式
  • RPC Server錯(cuò)誤處理
  • RPC Server 流式(Socket)服務(wù)

2.2 RPC Server接口暴露

定義方式1:使用JsonServiceExporter

// 注意:這里的beanName以 "/" 開頭,最終會(huì)被BeanNameUrlHandlerMapping處理
@Bean("/us")
JsonServiceExporter exporter(UserService userService, ObjectMapper objectMapper) {
  JsonServiceExporter exporter = new JsonServiceExporter() ;
  // 暴露的接口
  exporter.setServiceInterface(UserService.class) ;
  // 這里非必須設(shè)置
  exporter.setObjectMapper(objectMapper) ;
  // 對(duì)應(yīng)的接口實(shí)現(xiàn)
  exporter.setService(userService) ;
  return exporter ;
}

通過此種方式,我們就完成了服務(wù)的暴露,任何支持 JSON-RPC 的客戶端均可訪問此服務(wù),接口地址:http://localhost:8080/us

定義方式2:使用注解自動(dòng)發(fā)現(xiàn)機(jī)制

修改上面的接口已經(jīng)實(shí)現(xiàn)類,添加如下的注解:

@JsonRpcService("/us")
public interface UserService {
}
@AutoJsonRpcServiceImpl
@Service
@Primary
public class UserServiceImpl implements UserService {
}

接下來,還需要定義如下的bean(啟動(dòng)掃描功能)。

@Bean
AutoJsonRpcServiceImplExporter autoExporter() {
  return new AutoJsonRpcServiceImplExporter() ;
}

這里我們推薦使用注解的方式。

2.3 RPC Client調(diào)用

配置方式1:使用AutoJsonRpcClientProxyCreator

首先,確保接口上使用了@JsonRpcServer注解:

@JsonRpcService("/us")
public interface UserService {}

接下來,配置AutoJsonRpcClientProxyCreator:

@Bean
AutoJsonRpcClientProxyCreator proxyCreator() throws Exception {
  AutoJsonRpcClientProxyCreator creator = new AutoJsonRpcClientProxyCreator() ;
  // 該baseUrl會(huì)自動(dòng)拼接到@JsonRpcService的路徑前面; http://localhost:8080/us
  creator.setBaseUrl(URI.create("http://localhost:8080").toURL()) ;
  // 接口所在的包
  creator.setScanPackage("com.pack.rpc.server") ;
  return creator ;
}

配置方式2:使用JsonProxyFactoryBean

@Bean
JsonProxyFactoryBean userServiceProxy() {
  JsonProxyFactoryBean proxy = new JsonProxyFactoryBean() ;
  proxy.setServiceUrl("http://localhost:8080/us") ;
  proxy.setServiceInterface(UserService.class);
  return proxy ;
}

通過該FactoryBean,會(huì)自動(dòng)的為UserService接口創(chuàng)建代理。

配置方式3:使用JsonRpcHttpClient

上面2種方式都是依賴的Spring環(huán)境,下面我們還可以使用如下的2中方式創(chuàng)建客戶端:

JsonRpcHttpClient client = new JsonRpcHttpClient(URI.create("http://localhost:8080/us").toURL()) ;
User user = client.invoke("createUser", new Object[] { "Spring Boot3實(shí)戰(zhàn)案例200講", "Pack", "123456" }, User.class);
System.err.println(user) ;


// 也可以通過如下方式創(chuàng)建代理
JsonRpcHttpClient client = new JsonRpcHttpClient(URI.create("http://localhost:8080/us").toURL());
UserService userService = ProxyUtil.createClientProxy(
    ClientTest.class.getClassLoader(),
    UserService.class,
    client) ;
User user = userService.createUser("Pack", "xg") ;
System.err.println(user) ;

2.4 測(cè)試

@RestController
@RequestMapping("/rpc")
public class RpcController {
  private final UserService userService ;
  public RpcController(UserService userService) {
    this.userService = userService;
  }


  @GetMapping("/create")
  public ResponseEntity<User> createUser(String userName, String firstName, String password) {
    return ResponseEntity.ok(this.userService.createUser(userName, firstName, password)) ;
  }


  @GetMapping("/query")
  public ResponseEntity<User> queryUser(String userName) {
    return ResponseEntity.ok(this.userService.findUserByUserName(userName)) ;
  }
}

運(yùn)行結(jié)果

圖片圖片

圖片圖片

成功調(diào)用。

2.5 異常處理

我們按照上面接口實(shí)現(xiàn),我們通過如下參數(shù)訪問查詢接口:

圖片圖片

控制臺(tái)異常信息如下:

圖片圖片

RPC Client接收到如上的異常數(shù)據(jù)。

我們可以通過如下方式自定義異常信息,在JSON-RPC 服務(wù)的接口上添加注解:

@JsonRpcErrors({
  @JsonRpcError(exception = Exception.class, code = -1, message = "服務(wù)發(fā)生異常")
})
User findUserByUserName(String userName);

再次訪問上面的接口后,控制臺(tái)輸出:

圖片圖片

2.6 流式(Socket)服務(wù)

我們可以通過Socket方式提供服務(wù),如下示例:

服務(wù)端:

JsonRpcServer server = new JsonRpcServer(new UserServiceImpl()) ;
int maxThreads = 50 ;
int port = 8080 ;
ServerSocket serverSocket = new ServerSocket(port) ;
StreamServer ss = new StreamServer(server, maxThreads, serverSocket) ;


ss.start() ;

客戶端:

Socket socket = new Socket(InetAddress.getLocalHost(), 8080) ;
OutputStream os = socket.getOutputStream() ;


Map<String, Object> data = Map.of("jsonrpc", "2.0", "method", "createUser", 
  "params", new Object[] {"Spring Boot3實(shí)戰(zhàn)案例200講", "Pack", "111111"}, "id", "s-0001") ;
os.write(new ObjectMapper().writeValueAsBytes(data)) ;
socket.shutdownOutput(); 


InputStream is = socket.getInputStream() ;
System.err.println(new String(is.readAllBytes())) ;

運(yùn)行結(jié)果

圖片

客戶端輸出:

圖片 圖片

責(zé)任編輯:武曉燕 來源: Springboot全家桶實(shí)戰(zhàn)案例源碼
相關(guān)推薦

2022-02-16 16:28:22

RPC鴻蒙操作系統(tǒng)

2014-09-02 10:43:45

RedisRPC

2024-05-31 08:45:24

2023-05-26 01:05:10

2017-08-10 16:14:07

FeignRPC模式

2021-08-29 18:36:57

項(xiàng)目

2025-03-07 08:57:46

HTTP客戶端框架

2015-06-09 13:31:29

Hadoop RPC遠(yuǎn)源碼解析

2024-11-26 08:05:44

2025-02-07 09:11:04

JSON對(duì)象策略

2023-05-18 08:47:42

2019-06-21 14:48:25

RMI遠(yuǎn)程RPC

2024-01-31 18:02:47

OpenAISpringAI

2024-08-06 11:17:58

SpringJSON數(shù)據(jù)

2020-12-30 07:49:32

KubernetesJava Spring Clo

2018-06-06 14:30:38

Spring BootApplication事件

2022-10-26 07:14:25

Spring 6Spring業(yè)務(wù)

2022-04-01 17:25:19

銳捷網(wǎng)絡(luò)混合辦公多點(diǎn)辦公

2023-03-16 08:14:57

2025-02-22 08:00:00

AgentSpringBootJava
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)