springboot整合freemarker 自定义标签(实战)

使用springboot+shiro+freemarker做的管理系统,做到权限部分想到以前使用jsp整合shiro可以使用标签来控制权限:

<shiro:hasPermission name="admin:add">
    <label>这个用户拥有admin:add的权限</label>
</shiro:hasPermission>

现在使用freemarker实现类似的功能!

配置freemarker

spring: 
 # 配置freemarker
  freemarker:
    # 设置模板后缀名
    suffix: .ftl
    # 设置文档类型
    content-type: text/html
    # 设置页面编码格式
    charset: UTF-8
    # 设置页面缓存
    cache: false
    # 设置ftl文件路径
    template-loader-path:
      - classpath:/templates
    request-context-attribute: request

编写标签类

标签类实现TemplateDirectiveModel接口,并重写execute方法实现业务!

import java.io.IOException;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;

import com.pactera.ai.manage.commons.annotation.FreemarkerComponent;
import org.springframework.stereotype.Component;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
@Component
public class PermissionTagDirective implements TemplateDirectiveModel {

	private final static String  URL = "url";
	
	@SuppressWarnings("rawtypes")
	@Override
	public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
			throws TemplateException, IOException {
		//获取标签参数值  <@perm url="/test"> </@perm>
		String perm= params.get(URL).toString();
		if(!StringUtils.isBlank(perm)) {
			//判断用户是否拥有权限
			if(SecurityUtils.getSubject().isPermitted(perm)) {
                //显示标签内容
				body.render(env.getOut());
			}
		}
	}

}

注册标签到freemarker配置

@Component
public class CustomFreeMarkerConfigurer  implements ApplicationContextAware {
	
	@Autowired 
	Configuration configuration; 

	@Autowired
	PermissionTagDirective permissionTagDirective;

	@PostConstruct //在项目启动时执行方法
	public void setSharedVariable() throws IOException, TemplateException {
		       // 将标签perm注册到配置文件
		      configuration.setSharedVariable("perm", permissionTagDirective);
		  
	}

}

使用标签

//如果执行body.render(env.getOut()); 标签中的button会显示.否则不会显示
// 以此来实现按钮级别的权限控制
<@perm url="/test"> <button type="button" value="按钮"></button></@perm>

优化

这样已经实现自定义标签功能,但是如果标签很多那么每个标签都要执行  configuration.setSharedVariable实现注册,为了更优雅的实现,我们可以使用注解的方式实现。

自定义注解

@Target(value = ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface FreemarkerComponent {
	 String value() default "";
}

使用注解

// 定义PermissionTagDirective bean name="perm"
@FreemarkerComponent("perm")
public class PermissionTagDirective implements TemplateDirectiveModel {
	.....
}

根据注解注册标签

@Component
public class CustomFreeMarkerConfigurer  implements ApplicationContextAware {

	ApplicationContext applicationContext ;
	
	@Autowired 
	Configuration configuration; 
	
	@PostConstruct
	public void setSharedVariable() throws IOException, TemplateException {
		// 根据注解获取bean ,key is bean name ,value is bean object
		Map<String, Object> map = this.applicationContext.getBeansWithAnnotation(FreemarkerComponent.class);
		for (String key : map.keySet()) {
			configuration.setSharedVariable(key, map.get(key));
		}
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext=applicationContext;
	}

}

在实现了接口TemplateDirectiveModel类上使用注解FreemarkerComponent,那么类会自动注册为freemarker标签,且标签名称为类的name值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值