首页 > 编程知识 正文

adguard 广告拦截器,广告拦截器

时间:2023-05-03 11:15:40 阅读:181464 作者:3292

简介: mPaas-RPC拦截器在不同场景下的使用指南

1 .背景

金融级移动开发平台mpaas [1]为APP的开发、测试、运营和运维提供了云端对端一站式解决方案,有效降低了技术门槛,降低了研发成本其中,移动网关服务(Mobile Gateway Service,简称MGS )作为mPaas最重要的组件之一,连接移动客户端和服务端,简化移动端和服务端的数据协议和通信协议,提高开发效率在我们的日常运输过程中,我们发现很多用户在使用客户端RPC组件时,都有各种场合的诉求,包括通过拦截请求添加业务请求标记、免费注册、回复结果模拟、异常处理、流限制等。 本文旨在介绍利用RPC提供的拦截器机制,通过对不同实际场景的描述,用于业务参考。

2. RPC调用原理

App通过移动网关控制台访问后台服务后,调用RPC的示例代码如下:

rpcdemoclientclient=MP RPC.getrpcproxy (rpcdemoclient.class;

//设置请求

GetIdGetReq req=new GetIdGetReq (;

req.id='123 ';

req.age=14;

req.isMale=true;

//开始RPC请求

string response=client.getid get (req );

有趣的是,在整个调用过程中,实际上并不实现RpcDemoClient这个接口,而是通过MPRpc.getRpcProxy获得代理,并通过代理对象完成调用这里其实主要使用的是Java动态代理的技术。 调用RPC接口时,通过动态代理的RpcInvocationHandler回调已实现的invoke方法,最终在invoke内实现的数据序列化处理通过网络库

publictgetrpcproxy(classtclazz ) {

logcatutil.info('RPCfactory ',' clazz=[' clazz.getName );

return proxy.newproxyinstance (clazz.getclass loader )、new Class[]{clazz}和newrpcinvocationhandler (this.mconfining )

}

在业务开发中,如果在某些情况下需要控制来自客户端的网络请求(阻止网络请求、禁止访问特定接口或限制流),则可以通过RPC拦截器来实现。

RPC服务RPC服务=

getMicroApplicationContext ().findservicebyinterface (RPC service.class.getname ) );

RPC service.addrpcinterceptor (operation type.class,new CommonInterceptor );

3 .拦截器

原理

RPC目前采用拦截机制实现RPC的定制处理。 如下图所示,业务通过设定定制RpcIntercept,可以在要求前要求例外,将RPC的定制处理返回到3个阶段。 图1:rpc阻止程序调用图像

4 .预握手场景

全局添加业务定制请求头

典型使用情况:为业务添加自定义业务全局标识或其他统计字段

@ overridepublicbooleanprehandle (object proxy,

ThreadLocalObject retValue,byte[] retRawValue,

类? 类、

方法方法,

对象[ ] args,

Annotation annotation是,

ThreadLocalMapString,Object threadLocal ) throwsrpcexception {//do something .

rpcinvocationhandlerhandler=(rpcinvocationhandler ) proxy.getinvocationhandler ) proxy;

handler.getRpcInvokeContext ().addrequestheader ),) headerCustom ); 返回真; }阻止当前的rpc请求进程

典型的使用场景:例如,当前没有登录时,先屏蔽需要登录的rpc,提示统一登录

@ overridepublicbooleanprehandle (object proxy,

ThreadLocalObject retValue,byte[] retRawValue,

类? 类、

方法方法,

Object[] args,
Annotation annotation,
ThreadLocal<Map<String, Object>> threadLocal)throws RpcException {//Do something...
String operationType = getOperationType(aClass, method, args);if ("operationType1".equals(operationType)) {boolean isLogin = false;if (!isLogin) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {@Overridepublic void run() {
Toast.makeText(LauncherApplicationAgent.getInstance().getApplicationContext()," 当前未登录,请登录", Toast.LENGTH_SHORT).show();}});// 返回给上层调用登录失败的异常,上层做业务处理throw new RpcException(RpcException.ErrorCode.CLIENT_LOGIN_FAIL_ERROR, "login fail.");}}return true;}private String getOperationType(Class<?> aClass, Method method, Object[] args) {if (aClass == null || null == method) return "";
OperationType operationType = method.getAnnotation(OperationType.class);return operationType == null ? "" : operationType.value();} 5. postHandle场景
1. 拦截接口返回

典型使用场景:全局修改服务端的返回结果,比如mock服务端的数据
@Overridepublic boolean postHandle(Object proxy,
ThreadLocal<Object> threadLocal,byte[] retRawValue,
Class<?> aClass,
Method method,
Object[] args,
Annotation annotation) throws RpcException {//Do something...// 场景:修改服务端返回的数据,比如mock数据,或者修改服务端数据
String operationType = getOperationType(aClass, method, args);
LoggerFactory.getTraceLogger().debug(TAG, "postHandle:" + operationType);if ("operationType1".equals(operationType)) {
String value = JSON.parse(retRawValue).toString();
LoggerFactory.getTraceLogger().debug(TAG, "postHandle 原始返回" + value);
String mockData = "{"img":"imgPath","User":{"name":"我是mock的数据","age":18}}";
Object mockObj = JSON.parseObject(mockData, method.getReturnType());
threadLocal.set(mockObj);return true;}return true;}private String getOperationType(Class<?> aClass, Method method, Object[] args) {if (aClass == null || null == method) return "";
OperationType operationType = method.getAnnotation(OperationType.class);return operationType == null ? "" : operationType.value();}

6. exceptionHandle场景
1. 异常统一处理

比如登录态失效,服务端会统一返回2000的错误码,客户端可以在exceptionHandle里统一拦截进行登录态免登操作
@Overridepublic boolean exceptionHandle(Object proxy, ThreadLocal<Object> retValue, byte[] bytes, Class<?> aClass, Method method, Object[] objects,
RpcException rpcException, Annotation annotation) throws RpcException {
String operationType = getOperationType(aClass, method, objects);if (RpcException.ErrorCode.CLIENT_LOGIN_FAIL_ERROR == rpcException.getCode()&&"operationType1".equals(operationType)) {// 1. 去免登
hasLogin = true;// 2. 免登后在帮上层重发请求,免登操作对上层业务无感知try {
LoggerFactory.getTraceLogger().debug(TAG, "exceptionHandle. Start resend rpc begin " + operationType);// 重发请求
Object object = method.invoke(proxy, objects);
retValue.set(object);
LoggerFactory.getTraceLogger().debug(TAG, "exceptionHandle. Start resend rpc success");return false;} catch (Throwable e) {
LoggerFactory.getTraceLogger().error(TAG, "resend rpc occurs illegal argument exception", e);throw new RpcException(RpcException.ErrorCode.CLIENT_HANDLE_ERROR, e + "");}}return true;}

7. H5场景

由于H5场景中使用的jsapi的rpc,需要支持在js环境里传递到native环境,所以在设计上,是统一通过operationType: alipay.client.executerpc 接口进行的转发,所以针对H5发送的RPC请求,需要做特殊判断,通过入参拿到真实的operationType接口,示例代码如下。

1. 获取H5请求的接口名称和入参

var params = [{"_requestBody":{"userName":"", "userId":0}}]var operationType = 'alipay.mobile.ic.dispatch'
AlipayJSBridge.call('rpc', {
operationType: operationType,
requestData: params,
headers:{}}, function (result) {
console.log(result);});

业务通过jsapi去请求rpc,如何获取jsapi请求的rpc名称,可以参考代码如下

@Overridepublic boolean preHandle(Object o, ThreadLocal<Object> threadLocal, byte[] bytes, Class<?> aClass, Method method, Object[] objects, Annotation annotation, ThreadLocal<Map<String, Object>> threadLocal1) throws RpcException {
String operationType = getOperationType(aClass, method, objects);if ("alipay.client.executerpc".equals(operationType)) {// H5的rpc名称
String rpcName = (String) objects[0];// 入参
String req = (String) objects[1];
LoggerFactory.getTraceLogger().debug(TAG, "operationType:" + rpcName + " " + req);} else {// Native的rpc}
LoggerFactory.getTraceLogger().debug(TAG, "operationType:" + operationType);return true;}

参考文档

[1] mPaaS平台:https://www.aliyun.com/product/mobilepaas/mpaas

我们是阿里云智能全球技术服务-SRE团队,我们致力成为一个以技术为基础、面向服务、保障业务系统高可用的工程师团队;提供专业、体系化的SRE服务,帮助广大客户更好地使用云、基于云构建更加稳定可靠的业务系统,提升业务稳定性。我们期望能够分享更多帮助企业客户上云、用好云,让客户云上业务运行更加稳定可靠的技术。

原文链接:https://developer.aliyun.com/article/781269?

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。