最近博主在项目中,遇到了java对接jsonrpc的需求,稍微折腾了下,特整理一份笔记.本文主要记录的是jsonrpc4j (github地址:GitHub - briandilley/jsonrpc4j: JSON-RPC for Java)
环境:
引入依赖
<dependency><groupId>com.github.briandilley.jsonrpc4j</groupId><artifactId>jsonrpc4j</artifactId><version>1.6</version></dependency>
配置类:(注意url与字符集的设置)
一定要注意:
1. AutoJsonRpcServiceImplExporter (这里不单独配置的话,会引发rpc response返回123)
2.如果字符集不配置,可能会引发415错误,但是rpc response会返回一个105
import com.googlecode.jsonrpc4j.spring.AutoJsonRpcClientProxyCreator;import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImplExporter;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import .URL;@Configuration@Slf4jpublic class RpcConfiguration {@Bean@ConditionalOnProperty(value = {"ianp.external.rpc.client.url", "ianp.external.rpc.client.basePackage"})public AutoJsonRpcClientProxyCreator rpcClientProxyCreator(@Value("${ianp.external.rpc.client.url}") String url, @Value("${ianp.external.rpc.client.basePackage}") String basePackage) {log.info("local rpc config,url:{}, basePackage:{}", url, basePackage);AutoJsonRpcClientProxyCreator clientProxyCreator = new AutoJsonRpcClientProxyCreator();try {clientProxyCreator.setBaseUrl(new URL(url));clientProxyCreator.setContentType("application/json");} catch (Exception e) {log.error("create rpc url failed", e.getMessage());}clientProxyCreator.setScanPackage(basePackage);return clientProxyCreator;}@Beanpublic AutoJsonRpcServiceImplExporter rpcServiceImplExporter() {return new AutoJsonRpcServiceImplExporter();}}
yml片段:
ianp:external:rpc:client:url: http://localhost:7878/basePackage: com.xxx.backend.service.rpc
使用:
默认先声明一个对应的API,如:
@JsonRpcService是对应的接口地址,一般以rpc开头
import com.googlecode.jsonrpc4j.JsonRpcService;@JsonRpcService("/rpc")public interface StorageProfService {String proofOfExistence(String address, String maindata, String password);}
调用参考
import com.alibaba.fastjson.JSON;import com.xxx.backend.service.rpc.service.api.StorageProfService;import com.xxx.backend.service.rpc.service.pojo.StorageProf;import com.googlecode.jsonrpc4j.JsonRpcClientException;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Service@Slf4jpublic class StorageProfConsumerService {@Autowiredprivate StorageProfService storageProfService;public String storageProf(StorageProf storageProf) {String result = null;try {Object res = storageProfService.proofOfExistence(storageProf.getAddress(), storageProf.getMainData(),storageProf.getPassword());result = JSON.toJSONString(res);} catch (JsonRpcClientException ce) {String message = ce.getMessage();log.error("client error:{}", message);throw ce;}return result;}}
参考,这个demo很详细了:GitHub - Panlf/springboot-jsonrpc: 本项目是基于SpringBoot和Json-Rpc(jsonrpc4j)的案例,其实跟dubbo的调用是类似的。
补充说明:
1. 解决与RedisConfig的冲突
在实际整合使用的过程中,发现与RedisConfig自定义配置ObjectMapper冲突
原始方案:
// @Bean// public ObjectMapper messagePackObjectMapper() {// return new ObjectMapper(new MessagePackFactory())//.registerModule(new JavaTimeModule())//.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);// }
修改后的方案:
@PostConstruct public void registerModule() { objectMapper.registerModule(new JavaTimeModule()).disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); }