【仅供内部供应商使用,不提供对外解答和培训】

Page tree

【仅供内部供应商使用,不提供对外解答和培训】

Skip to end of metadata
Go to start of metadata

一、特殊名词介绍

二、背景、场景介绍

早期帆软产品中绝大部分的WEB服务都是通过op和cmd这两个参数来指定的。因为客户的场景差异,不同的客户对相同的服务的处理过程有时候是不完全一致的,这个时候就需要对其中的部分服务进行改造。

所以就开放了RequestInterceptor接口。这个接口在8.0和9.0版本的产品中用途比较多,10.0中则使用得非常少了。但是他们的功能都不变。

1、替换原有的某op/cmd绑定的Action类

2、为某个已经存在的op服务,扩充新的cmd服务

三、接口介绍

RequestInterceptor .java
package com.fr.stable.fun;

import com.fr.plugin.injectable.SpecialLevel;
import com.fr.stable.StringUtils;
import com.fr.stable.fun.mark.Layer;
import com.fr.stable.fun.mark.Mutable;
import com.fr.stable.web.RequestCMDReceiver;

/**
 * Created by richie on 16/8/9.
 * 请求拦截器,通过传递op和cmd进行内置请求的拦截
 */
public interface RequestInterceptor extends Mutable, RequestCMDReceiver, Layer {

    String MARK_STRING = SpecialLevel.RequestInterceptor.getTagName();

    int CURRENT_LEVEL = 1;

    class ActionKey {

        private String op;
        private String cmd;
        private String pluginID;

        public static ActionKey create(String op, String cmd, String pluginID) {
            if (pluginID == null) {
                pluginID = StringUtils.EMPTY;
            }
            return new ActionKey(op, cmd, pluginID);
        }

        private ActionKey(String op, String cmd, String pluginID) {
            this.op = op;
            this.cmd = cmd;
            this.pluginID = pluginID;
        }

        public String getOp() {
            return op;
        }

        public String getCmd() {
            return cmd;
        }

        public String getPluginID() {
            return pluginID;
        }

        @Override
        public boolean equals(Object o) {

            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            ActionKey actionKey = (ActionKey) o;

            return op.equals(actionKey.op) && cmd.equals(actionKey.cmd) && pluginID.equals(actionKey.pluginID);
        }

        @Override
        public int hashCode() {
            int result = op.hashCode();
            result = 31 * result + cmd.hashCode();
            result = 31 * result + pluginID.hashCode();
            return result;
        }
    }
}

AbstractRequestInterceptor .java
package com.fr.stable.fun.impl;

import com.fr.stable.fun.RequestInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by richie on 16/8/9.
 */
public abstract class AbstractRequestInterceptor extends AbstractProvider implements RequestInterceptor {

    public String mark4Provider() {
        return getClass().getName();
    }

    public int currentAPILevel() {
        return CURRENT_LEVEL;
    }

    public void actionCMD(HttpServletRequest req, HttpServletResponse res, String sessionID) throws Exception {

    }

    @Override
    public void actionCMD(HttpServletRequest req, HttpServletResponse res) throws Exception {

    }

    @Override
    public int layerIndex() {
        return CURRENT_LEVEL;
    }
}


四、支持版本

产品线

版本

支持情况

备注

FR8.0支持
FR9.0支持
FR10.0支持只能用于报表场景的web服务提供
BI3.6支持
BI4.0支持
BI5.1支持不推荐使用
BI5.1.2支持不推荐使用
BI5.1.3支持不推荐使用

五、插件注册

plugin.xml
<extra-core>
        <RequestInterceptor class="your class name" op="", cmd="", pluginId=""/>
</extra-core>

六、原理说明

接口注册逻辑:插件引擎在加载插件时,会通过ExtraClassManager#mountSpecific识别出ACTION类型的接口。再通过addHackActionCMD方法注入到hackActionMap对象中

接口生效逻辑:CMD请求分发器在分发请求时,会先从已注册的cmd中进行匹配,当op/cmd/pluginId均匹配时,会将请求分发给对应的接口处理。

注:所以开发者在使用op/cmd这套服务的时候一定要使用产品自身的分发器分发请求,否则开发的插件就不支持这个接口了。

七、特殊限制说明

接口的op配置 来源于一个WebService对象。每个WebService对象都包含一组RequestCMDReceiver,也就是cmd参数的来源。而pluginId则是一个比较特殊的配置。

如果前端调用请求时没有传递pluginId,则这个配置留空或者不配置(一般只改后端,不动前端的情况就不会涉及到pluginID)。

如果有多个插件都对某一个cmd请求重写了,而调用时需要指定具体的某个插件的cmd生效,则调用时除op和cmd参数外还需指定pluginId。这里的pluginId与我们配置中的pluginId相同即可。

八、常用链接

demo地址:demo-request-interceptor

com.fr.stable.web.RequestCMDReceiver

com.fr.web.core.ActionNoSessionCMD

com.fr.web.core.WebActionsDispatcher

三组开放web服务接口的插件接口对比

插件中四种实现filter功能的接口对比

九、开源案例

免责声明:所有文档中的开源示例,均为开发者自行开发并提供。仅用于参考和学习使用,开发者和官方均无义务对开源案例所涉及的所有成果进行教学和指导。若作为商用一切后果责任由使用者自行承担。


  • No labels