soul从入门到放弃8--自定义单一职责插件

2021-01-23  本文已影响0人  滴流乱转的小胖子

一、前戏-- 功能需求

通过上一篇对soul插件链的整体概览学习,本篇开始“生搬硬套”,尽量符合soul的编码方式实现一个自定义单一职责插件。

需求:实现一个参数验签的插件,验签失败中断调用链调用直接返回错误信息,否则执行剩下调用链。

二、自定义插件类

execute() 方法为核心的执行方法,用户可以在里面自由的实现自己想要的功能。

getOrder() 指定插件的排序。

named() 指定插件的名称。

skip() 在特定的条件下,该插件是否被跳过。

此处附上一个小demo:

@Slf4j
public class CustomSignPlugin implements SoulPlugin {
    /**
     * 加密私钥
     */
    private String privateKey = "CDRjzk2sb99v6nUkXx8+6g";

    @Override
    public String named() {
        return PluginEnum.CUSTOMSIGN.getName();
    }
    @Override
    public Boolean skip(final ServerWebExchange exchange) {
        final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
        return !Objects.equals(Objects.requireNonNull(soulContext).getRpcType(), RpcTypeEnum.HTTP.getName());
    }
    @Override
    public Mono<Void> execute(ServerWebExchange exchange, SoulPluginChain chain) {
        final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
        String queryParam = exchange.getRequest().getURI().getQuery();
        if (StringUtils.isNotBlank(queryParam)) {
            if(!checkSignature(exchange.getRequest())) {
                log.error("接口请求验签失败");
                Object error = SoulResultWrap.error(SoulResultEnum.CHECK_CUSTOM_SIGN_EXCEPTION.getCode(), SoulResultEnum.CHECK_CUSTOM_SIGN_EXCEPTION.getMsg(), null);
                return WebFluxResultUtils.result(exchange, error);
            }
        }
        return chain.execute(exchange);
    }

    private boolean checkSignature(ServerHttpRequest request) {
        Map<String, String> map = request.getQueryParams().toSingleValueMap();
        String signReq = map.containsKey("sign")? map.get("sign").toString() : null;;
        boolean checkSignture = false;
        //验证签名
        if (map.size() > 0 && StringUtils.isNotBlank(signReq)) {
            //签名匹配,则签名认证通过
            map.remove("sign");
            if (signReq.equals(Signature.getSign(map, privateKey))
                || signReq.equalsIgnoreCase(Signature.getSign(map, privateKey))) {
                checkSignture = true;
            }
        } else {
            // 不传签名,非法强求
            checkSignture = false;
        }
        return checkSignture;
    }

    @Override
    public int getOrder() {
        return PluginEnum.CUSTOMSIGN.getCode();
    }
image.png

三、设置插件执行顺序

在PluginEnum类中创建,自定义插件的执行顺序,名字等信息。

ps:1.枚举中code定义相对松散,这个间隔目前怀疑是为了便于“渗入”新插件

image.png

2.枚举类中的name一定要定义好且具有唯一性,后文配置中还会用到

四、设置异常

SoulResultEnum类中定义统一错误异常码,此处建议使用英文,此处用中文作以区分。

image.png

五、封装spring-starter

<dependency>
    <groupId>org.dromara</groupId>
    <artifactId>soul-plugin-customsign</artifactId>
    <version>${project.version}</version>
</dependency>
@Configuration
public class CustomSignPluginConfiguration {
    /**
     * init SoulPlugin.
     *
     * @return {@linkplain SoulPlugin}
     */
    @Bean
    public SoulPlugin customSignPlugin() {
        return new CustomSignPlugin();
    }
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.dromara.soul.spring.boot.plugin.divide.DividePluginConfiguration
image.png

六、soul-bootstrap的配置

此处配置就“过于”简单,只需要引入maven依赖即可,体现出作者对代码的高内聚、低耦合了,nice!

<pre><dependency>
<groupId>org.dromara</groupId>
<artifactId>soul-spring-boot-starter-plugin-customsign</artifactId>
<version>${project.version}</version>
</dependency></pre>

七、配置插件信息

mvn  clean package install -Dmaven.test.skip=true -Dmaven.javadoc.skip=true -Drat.skip=true -Dcheckstyle.skip=true
image.png

八、测试

image.png

一发入魂,搞定! 收拾收拾可以再睡一会了。

九、小结

上一篇下一篇

猜你喜欢

热点阅读