1. 程式人生 > >SpringBoot-----JsonRpc跨語言遠端呼叫協議

SpringBoot-----JsonRpc跨語言遠端呼叫協議

1、JsonRpc概念

JSON-RPC是一種基於JSON的跨語言遠端呼叫協議。有文字傳輸資料小,便於除錯擴充套件的特點。

2、實現例子

a)專案1-api 編寫rpc介面

ProductRpc.java

package com.imooc.api;

import java.util.List;

import com.googlecode.jsonrpc4j.JsonRpcService;
import com.imooc.api.domain.ProductRpcReq;
import com.imooc.entity.Product;

/**
 * 產品相關的rpc服務
 * @author zemel
 *
 */
@JsonRpcService("rpc/products")
public interface ProductRpc {

	/**
	 * 查詢多個產品
	 * @param req
	 * @return
	 */
	List<Product> query(ProductRpcReq req);
	
	/**
	 * 查詢單個產品
	 * @param id
	 * @return
	 */
	Product findOne(String id);
	
	
}
package com.imooc.api.domain;

import java.math.BigDecimal;
import java.util.List;

/**
 * 產品相關rpc請求物件
 * @author zemel
 *
 */
public class ProductRpcReq {

	private List<String> idList;
	private BigDecimal minRewardRate;
	private BigDecimal maxRewardRate;
	private List<Integer> statusList;
	
	public List<String> getIdList() {
		return idList;
	}
	public void setIdList(List<String> idList) {
		this.idList = idList;
	}
	public BigDecimal getMinRewardRate() {
		return minRewardRate;
	}
	public void setMinRewardRate(BigDecimal minRewardRate) {
		this.minRewardRate = minRewardRate;
	}
	public BigDecimal getMaxRewardRate() {
		return maxRewardRate;
	}
	public void setMaxRewardRate(BigDecimal maxRewardRate) {
		this.maxRewardRate = maxRewardRate;
	}
	public List<Integer> getStatusList() {
		return statusList;
	}
	public void setStatusList(List<Integer> statusList) {
		this.statusList = statusList;
	}
	@Override
	public String toString() {
		return "ProductRpcReq [idList=" + idList + ", minRewardRate=" + minRewardRate + ", maxRewardRate="
				+ maxRewardRate + ", statusList=" + statusList + "]";
	}
	
}

b)專案2-manager(rpc實現工程)

ProductRpcImpl.java

package com.imooc.rpc;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImpl;
import com.imooc.api.ProductRpc;
import com.imooc.api.domain.ProductRpcReq;
import com.imooc.entity.Product;
import com.imooc.service.ProductService;

/**
 * rpc服務實現類
 * @author zemel
 *
 */
@AutoJsonRpcServiceImpl
@Service
public class ProductRpcImpl implements ProductRpc{
	
	private static Logger log = LoggerFactory.getLogger(ProductRpcImpl.class);

	@Autowired
	private ProductService productService;
	
	@Override
	public List<Product> query(ProductRpcReq req) {
		log.info("查詢多個產品,請求:{}", req);
		Pageable pageable = new PageRequest(0, 1, Sort.Direction.DESC, "rewardRate");
		Page<Product> page = productService.query(req.getIdList(), req.getMinRewardRate(), 
				req.getMaxRewardRate(), req.getStatusList(), pageable);
		log.info("查詢多個產品,結果:{}", page);
		return page.getContent();
	}

	@Override
	public Product findOne(String id) {
		log.info("查詢產品詳情,請求:{}", id);
		Product result = productService.findOne(id);
		log.info("查詢產品詳情,結果:{}", result);
		return result;
	}

}

RpcConfig.java

package com.imooc.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImplExporter;

/**
 * rpc相關配置
 * @author zemel
 *
 */
@Configuration
public class RpcConfig {

	@Bean
	public AutoJsonRpcServiceImplExporter rpcServiceImplExporter(){
		return new AutoJsonRpcServiceImplExporter();
	}
}
#伺服器
server.port=80
server.servlet.contextPath=/manager
   
# DataSource 
spring.datasource.url=jdbc:mysql://localhost/manager?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC 
spring.datasource.username=root
spring.datasource.password=
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

#jackson自定義日期格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

# JPA
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update

# 配置swagger
swagger.groupName=manager
swagger.basePackage=com.imooc.controller

c)rpc客戶端-saller

ProductRpcService.java

package com.imooc.seller.service;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import com.imooc.api.ProductRpc;
import com.imooc.api.domain.ProductRpcReq;
import com.imooc.entity.Product;
import com.imooc.entity.enums.ProductStatus;

/**
 * 產品服務
 * @author zemel
 *
 */
@Service
public class ProductRpcService {
	private static Logger log = LoggerFactory.getLogger(ProductRpcService.class);

	@Autowired
	private ProductRpc productRpc;
	
	/**
	 * 查詢全部產品
	 * @return
	 */
	public List<Product> findAll(){
		
		ProductRpcReq req = new ProductRpcReq();
		List<Integer> status = new ArrayList<>();
//		status.add(ProductStatus.IN_SELL.getCode());
//		req.setStatusList(status);
		
		log.info("rpc查詢全部產品,請求:{}", req);
		List<Product> result = productRpc.query(req);
		log.info("rpc查詢全部產品,結果:{}", result);
		
		return result;
	}
	
	@PostConstruct
	public void testFindAll(){
		findAll();
	}
	
	
}

RpcConfig.java

package com.imooc.seller.config;

import java.net.MalformedURLException;
import java.net.URL;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import com.googlecode.jsonrpc4j.spring.AutoJsonRpcClientProxyCreator;
import com.imooc.api.ProductRpc;

/**
 * rpc 相關配置
 * @author zemel
 *
 */
@Configuration
@ComponentScan(basePackageClasses={ProductRpc.class})
public class RpcConfig {
	
	private static Logger log = LoggerFactory.getLogger(RpcConfig.class);

	@Bean
	public AutoJsonRpcClientProxyCreator rpcClientProxyCreator(@Value("${rpc.manager.url}") String url){
		AutoJsonRpcClientProxyCreator creator = new AutoJsonRpcClientProxyCreator();
		try {
			creator.setBaseUrl(new URL(url));
		} catch (MalformedURLException e) {
			log.error("建立rpc服務地址錯誤", e);
			e.printStackTrace();
		}
		creator.setScanPackage(ProductRpc.class.getPackage().getName());//掃描rpc所在包
		
		return creator;
	}
	
}

application.properties

server.servlet.contextPath=/seller
server.port=8082
  
rpc.manager.url=http://localhost:80/manager/

# DataSource 
spring.datasource.url=jdbc:mysql://localhost/manager?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC 
spring.datasource.username=root
spring.datasource.password=
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.driver-class-name=com.mysql.jdbc.Driver