记一次去除Result处理
# 前言
我们现在项目中通过dubbo或http请求调用其他系统时, 总会获取到外层包装了Result类型的返回值, 然后依据Result里的code码来判断具体出现了那些问题, 然后抛出异常. 期间可能出现调用超时, 无权限, 等通用的异常情况, 这一步的操作很麻烦, 而且绝大部分都是通用代码, 并且返回值从
Result<T>
改变为了T
, 无法使用切面来处理, 每次写处理Result的相同代码烦的要死
# 原来的处理逻辑
public Sku query(ProductSkuQueryDTO param) {
try {
Result<Sku> result = productClient.query(param);
if (result == null) {
LOGGER.error("调用商品系统失败,返回结果result为空;入参param = {}", JSON.toJSONString(param));
throw new CustomErrorCodeException(ResultCode.FAIL.getCode(), "商品系统");
}
if (result.getCode() <= ResultCode.FAIL.getCode()) {
LOGGER.error("调用商品系统失败,返回值code码为负数;入参param = {}, 返回值result = {},", JSON.toJSONString(param), JSON.toJSONString(result));
throw new CustomErrorCodeException(result.getCode(), result.getMsg());
}
return result.getData();
} catch (CustomErrorCodeException e) {
throw e;
} catch (Exception e) {
LOGGER.error("调用商品系统异常;入参param = {}", JSON.toJSONString(param), e);
throw new CustomErrorCodeException(ResultCode.FAIL.getCode(), "商品系统");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 现在的逻辑
遇到这个问题后我发现使用内部类的方式可以完美解决这个问题, 虽然还是每个代码里都需要处理, 但是只需要一行就够了
# 工具类
/**
* client调用工具类
*
* @author yuyu
* @date 2021/4/9 5:28 下午
*/
public class CallClientResultUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(CallClientResultUtil.class);
/**
* client调用错误码处理
*
* @param param 参数
* @param logName 日志名称
* @param callClientResultInterface 需要执行的代码
* @param <P> 参数类型
* @param <R> 返回值类型
* @return
*/
public static <P, R> R executeWithLog(P param, String logName, CallClientResultInterface<P, R> callClientResultInterface) {
try {
Result<R> result = callClientResultInterface.execute(param);
if (result == null) {
LOGGER.error("调用【{}】失败,返回结果result为空;入参param = {}", logName, JSON.toJSONString(param));
throw new CustomErrorCodeException(ResultCode.FAIL.getCode(), logName + "调用失败");
}
if (result.getCode() <= ResultCode.FAIL.getCode()) {
LOGGER.error("调用【{}】失败,返回值code码为负数;入参param = {}, 返回值result = {},", logName, JSON.toJSONString(param), JSON.toJSONString(result));
throw new CustomErrorCodeException(result.getCode(), result.getMsg());
}
return result.getData();
} catch (CustomErrorCodeException e) {
throw e;
} catch (Exception e) {
LOGGER.error("调用【{}】异常;入参param = {}", logName, JSON.toJSONString(param), e);
throw new CustomErrorCodeException(ResultCode.FAIL.getCode(), logName + "调用异常");
}
}
public interface CallClientResultInterface<P, R> {
/**
* 执行
*/
Result<R> execute(P param);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 使用
public Sku query(ProductSkuQueryDTO param) {
return CallClientResultUtil.executeWithLog(param, "商品系统-query", p -> productClient.query(p));
}
1
2
3
2
3
# 结语
内部类的这种使用方式是在在第一次看线程池源码时学到的, 活学活用, 我可真棒
上次更新: 2021/06/09, 11:15:04