使用springboot+shiro+freemarker做的管理系统,做到权限部分想到以前使用jsp整合shiro可以使用标签来控制权限:
现在使用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());
}
}
}
}
@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"> @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 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值