【笔记】jsonrpc4j的异常抛出处理

第一次抛开restful,改用jsonrpc2.0方式提供接口,其中也遇到了不少问题,由此记录一下。

一,协议基本介绍百度搜索 jsonrpc2.0,这里就不细说了。

二,前置配置

        1,引入pom.xml。

        <!-- jsonrpc start -->
        <dependency>
            <groupId>com.github.briandilley.jsonrpc4j</groupId>
            <artifactId>jsonrpc4j</artifactId>
            <version>1.5.3</version>
        </dependency>
        <!-- jsonrpc end -->

        2,配置类

package com.config;

import com.googlecode.jsonrpc4j.MultipleInvocationListener;
import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImplExporter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * 1,格式参照jsonrpc格式
 *
 * @Description TODO
 * @Author zhaojilong
 * @Date 2021/9/27 11:14
 * @Version 1.0
 **/
@Configuration
@ComponentScan(basePackages = {"com.rpcservice"})
public class RpcConfig {

    @Bean
    public AutoJsonRpcServiceImplExporter rpcServiceImplExporter() {
        AutoJsonRpcServiceImplExporter rpc = new AutoJsonRpcServiceImplExporter();
        rpc.setRegisterTraceInterceptor(true);
        MultipleInvocationListener invocationListener = new MultipleInvocationListener();
        rpc.setInvocationListener(invocationListener);
        rpc.setShouldLogInvocationErrors(false);
        rpc.setContentType("application/json-rpc;charset=utf-8");
        //替换默认的json序列化
        //rpc.setObjectMapper(ModelObject.OBJECT_MAPPER);
        //自定义错误处理器,便于记录log
        //rpc.setErrorResolver(new CodeRpc());
        return rpc;
    }
}

3,接口类,这里服务名是否必须以 rpc/ 打头,可以再试试

package com.rpcservice;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.googlecode.jsonrpc4j.JsonRpcParam;
import com.googlecode.jsonrpc4j.JsonRpcService;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * 操作日志 rpc接口
 * jsonrpc协议
 * 服务名必须以 rpc/ 打头
 */
@JsonRpcService("/rpc/sysOrgDept")
public interface RpcSysOrgDeptService {

    /**
     * 分页查询
     * @param page
     * @return
     */
    ResultData findPage(@JsonRpcParam("page") Page page);

}

4,接口实现类

package com.rpcservice.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.googlecode.jsonrpc4j.JsonRpcClientException;
import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.Arrays;
import java.util.List;

/**
 * @Description TODO
 * @Author zhaojilong
 * @Date 2021/9/23 9:49
 * @Version 1.0
 **/
@Service
@AutoJsonRpcServiceImpl
@Slf4j
public class RpcSysOrgDeptServiceImpl implements RpcSysOrgDeptService {

    @Override
    public ResultData findTree() {
        log.debug("start findTree method");
        JSONArray deptTree = new JSONArray();
        return ResultData.success();
    }

}

5,访问地址                                                                                                                                

三,遇到的问题

        1, 传参问题

                1) jsonrpc请求一般为get和post。而post居多,也方便传入参数。如果用get,则所有的参数都需要urlencode转码。

                2) 如果接口定义的参数是对象,则传入参数也需要以对象传入(普通http请求,在controller接收参数,一个@requestbody就搞定了)。如果没有值,也必须传{}(这就很不爽- -)

         2, 异常抛出

                1) 我自己遇到的一个问题。如果程序发生异常或者自定义异常,正确的返回值应该是:

        

{
    "id": 0,
    "jsonrpc": "2.0",
    "error": {
        "code": -36010,
        "message": "自定义提示",
        "data":null
    }
}

而我当时只要是异常抛出,永远都是下面这样的

{
    "id": 0,
    "jsonrpc": "2.0",
    "result": null
}

这是因为我之前写过拦截器,将返回值给拦截了然后null处理了(这蛋疼了相当久,希望读者不要遇到这个问题- -),一般是不会有这问题出现的

                2) 当我处理完上面的问题后,发现jsonrpc没法自定义错误code,只能自定义错误message。抛出异常的写法:

throw new JsonRpcClientException(-32002, "请传入正确的名称", null);

然后收到的是:

{
    "id": 0,
    "jsonrpc": "2.0",
    "error": {
        "code": -36001,
        "message": "请传入正确的名称",
        "data":null
    }
}

发现有上面不同没有,抛出的code是-32002,返回的是-36001。然后就去看jsonrpc4j的代码,找到它是在这个类进行默认处理了,统一的错误code都是-36001,所以才没生效

                3) 解决方法:

                                重写这个类        

package com.googlecode.jsonrpc4j;

import com.fasterxml.jackson.databind.JsonNode;
import com.googlecode.jsonrpc4j.ErrorData;
import com.googlecode.jsonrpc4j.ErrorResolver;
import com.googlecode.jsonrpc4j.JsonRpcClientException;

import java.lang.reflect.Method;
import java.util.List;

import static com.googlecode.jsonrpc4j.ErrorResolver.JsonError.ERROR_NOT_HANDLED;

/**
 * 重写jsonrpc2.0中的异常处理类
 * @Description TODO
 * @Author zhaojilong
 * @Date 2021/10/22 11:21
 * @Version 1.0
 **/
public enum DefaultErrorResolver implements ErrorResolver {
    INSTANCE;

    /**
     * {@inheritDoc}
     */
    public JsonError resolveError(Throwable t, Method method, List<JsonNode> arguments) {
        //新增异常判断,并且带入错误code
        if (t instanceof JsonRpcClientException) {
            JsonRpcClientException rpcException = ((JsonRpcClientException) t);
            return new JsonError(rpcException.getCode(), rpcException.getMessage(), new ErrorData(t.getClass().getName(), rpcException.getMessage()));
        }
        return new JsonError(ERROR_NOT_HANDLED.code, t.getMessage(), new ErrorData(t.getClass().getName(), t.getMessage()));
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值