前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于jfinal Template的Shiro 标签

基于jfinal Template的Shiro 标签

作者头像
冷冷
发布2018-02-08 12:58:10
1.1K0
发布2018-02-08 12:58:10
举报
文章被收录于专栏:冷冷冷冷

jfinal template 经过 3.0、3.1 两个版本的迭代,已经非常稳定优秀了,所以我从传统的jsp 迁移到了jf template ,jsp中使用shiro 的标签库,可以很方便的实现权限的控制例如:

代码语言:javascript
复制
<shiro:guest>  
    用户未登录状态显示
</shiro:guest>  

<shiro:user>  
    欢迎[<shiro:principal/>]登录
</shiro:user>  

结合jf模板灵活指令扩展,来实现这么一套标签非常简单。

继承Directiv形式

代码语言:javascript
复制
public class GuestTag extends Directiv {
    private Subject getSubject() {
        return SecurityUtils.getSubject();
    }
    
    public void exec(Env env, Scope scope, Writer writer) {
        if (getSubject() == null || getSubject().getPrincipal() == null)
            stat.exec(env, scope, writer);
    }

    public boolean hasEnd() {
        return true;
    }
}


在config中配置
public void configEngine(Engine me) {
     me.addDirective("guest", new GuestTag());
}

页面中使用
#guest()
    用户未登录状态显示
#end

带入参类型标签处理

代码语言:javascript
复制
public class HasRoleTag extends Directiv {
    private Expr[] exprs;
    
     private Subject getSubject() {
        return SecurityUtils.getSubject();
    }
    
    public void setExprList(ExprList exprList) {
        exprs = exprList.getExprArray();
    }

    public void exec(Env env, Scope scope, Writer writer) {
        boolean hasRole = false;
        if (getSubject() != null && ArrayUtil.isNotEmpty(exprs))
            if (getSubject().hasRole(exprs[0].toString()))
                hasRole = true;

        if (hasRole)
            stat.exec(env, scope, writer);
    }

    public boolean hasEnd() {
        return true;
    }

}


页面中使用

#hasRole(roleName)
    body
#end

共享对象扩展

使用这种形式就更舒服了

代码语言:javascript
复制
public class ShiroTag {
    private Subject getSubject() {
        return SecurityUtils.getSubject();
    }
   
    public boolean isGuest() {
        return getSubject() == null || getSubject().getPrincipal() == null;
    }
 
    public boolean hasRole(String roleName) {
        return getSubject() != null && getSubject().hasRole(roleName);
    }
 
  
    public boolean lacksRole(String roleName) {
        boolean hasRole = getSubject() != null
                && getSubject().hasRole(roleName);
        return !hasRole;
    }
}

config中配置一下

代码语言:javascript
复制
public void configEngine(Engine me) {
    me.addSharedObject("shiro",ShiroTag);
}

页面使用
#if(shiro.hasRole(roleName))
body
#end

打完 收工~

指令注解加载

shiro标签种类很多,具体的逻辑也可以自己实现,所以我们写好以后,配置在config 是一件比较痛苦的事情,稍不留神,就配置错误了。所以我们可以通过注解扫描的形式方便配置。(其他自定义指令 也可以使用,方法相同)

代码语言:javascript
复制
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
//@Inherited 不继承
public @interface DefineDirective {
    /**
     * 标签名称
     *
     * @return String
     */
    String tag() default "";
}


@DefineDirective(tag = "hasRole")
public class HasRoleTag extends Directiv {...}

然后写这么一个EngineKit

代码语言:javascript
复制
    //classUtils  使用的是 hutool 工具包的方法。。。
    public static void addShiroDefineDirective(Engine me) {
        Set<Class<?>> classes = ClassUtil.scanPackageByAnnotation(defineDirective, DefineDirective.class);
        for (Class<?> clazz : classes) {
            DefineDirective defineDirective = clazz.getAnnotation(DefineDirective.class);
            String tag = defineDirective.tag();
            if (StrUtil.isNotEmpty(tag)) {
                me.addDirective(tag, (Directive) ClassUtil.newInstance(clazz));
            } else {
                LogKit.error("自定义Directive的标签为空无效:" + clazz.getName());
            }
        }
    }

config中配置一下

代码语言:javascript
复制
public void configEngine(Engine me) {
    EngineKit.addShiroDefineDirective(me);
}

PS

当然上边的扩展,并没有和我们的shiro插件集成,我实现了一个与JfinalShiroPlugin@玛雅牛无缝集成的版本内置这个shiro标签,原理类似。

JfinalShiroPlugin: http://git.oschina.net/log4j/jfinalshiroplugin

然后具体使用项目整合栗子: http://git.oschina.net/log4j/LMS

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 继承Directiv形式
  • 共享对象扩展
  • 指令注解加载
  • PS
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档