互联网飞速,无论公司大小,内部都会有各种系统,系统间调用随处可见。
作为开发人员每天都跟接口打交道,解析接口结果的代码占满屏幕。
but,接口返回结果格式大同小异,洁癖的毛病是不是又要犯了?
{
"data": "ok", //data有时是result,不同的系统有不同的名字
"msg": "ok", //msg可能是message
"status": 200 //status可能是code
}
经常看到的代码是这样的
结果处理起来挺简单的,像这样
String response ;
try {
response = orderListFeign.query(xxx);
} catch (RpcException e) {
logger.error("参数:{} , error:{}", xxx,e);
throw new BusinessException("xxx");
}
JSONObject json = JSONObject.fromObject(response);
String status = json.getString("status") ;
if(!"1".equals(status)) {
throw new BusinessException(json.getString("msg"));
}
JSONArray data = json.getJSONArray("data");
// resolve data
上面的代码遍布整个项目,这样不好吧[甚至代码更差],let me see?
状态值、错误提示、参数统一处理吧?切面 ,自定义注解试试吧 ?
talk is cheap
先定义个注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ResponseResolve {
String codeKey() default "status";
int codeSuccessValue() default 1;
String dataKey() default "data";
String messageKey() default "msg";
}
哪里需要@哪里,仔细看两个的区别
@FeignClient(name = "orderName", url = "${xxx1.server.domain}", configuration = CustomFeignConfig.class)
public interface OrderListFeign{
@ResponseResolve // 接口返回的json是 status,msg,data
@RequestMapping(value = "/api/order/query", method = RequestMethod.GET)
String query(@RequestParam String code);
}
@FeignClient(name = "addressName", url = "${xxx2.server.domain}", configuration = CustomFeignConfig.class)
public interface AddressFeign{
@ResponseResolve(codeKey="code",dataKey="result") // 接口返回的json是 code,msg,result
@RequestMapping(value = "/api/address/query", method = RequestMethod.GET)
String query(@RequestParam String code);
}
Aspect处理一下吧
@Slf4j
@Aspect
@Component
public class ResponseAspect {
private String getArgs(Object[] argsObj){
return Arrays.stream(argsObj).filter(e->e!=null).map(e->e.toString()).collect(Collectors.joining(","));
}
@Around("@annotation(respResolve)")
public Object rpcBasicResolve(JoinPoint joinPoint, ResponseResolve respResolve){
String args = getArgs(joinPoint.getArgs());
String method = joinPoint.getTarget().getClass().getSimpleName() + "#" + joinPoint.getSignature().getName();
Object response ;
try {
response = ((ProceedingJoinPoint)joinPoint).proceed();
} catch (Throwable throwable) {
log.error("api调用异常,method:{} ,args:{} ",method, args);
throw new RpcException("api调用异常");
}
JSONObject result = JSON.parseObject(response.toString());
if(!Integer.valueOf(respResolve.codeSuccessValue()).equals(result.getInteger(respResolve.codeKey()))){//根据注解中的codeKey与codeSuccessValue 统一判断返回状态
String message = result.getString(respResolve.messageKey());//根据注解获取提示消息
log.error("api调用接口 method:{} ,args:{} ,msg : {}",method, args,message);
throw new BusinessException(message);
}
return result.getString(respResolve.dataKey());// 根据注解中的data属性取得结果
}
}
service开心了,直接取得的结果内容
相比之前一堆代码是不是省劲多了
不用考虑状态码是code还是status ,result还是data了
String data = orderListFeign.query(xxx);
现在看是不是优秀了一点点
网友评论