springboot + Thymeleaf自定义标签

  • Post author:
  • Post category:其他


概述:

我的博客的标题我需要显示出当前在哪个页面,如”后台首页-XX的博客”,”文章管理-XX的博客”,

如果说我把对象每个页面都传递过去那肯定是没有问题的,但是我并不想,于是就开始找解决办法,最开始用拦截器解决,实现倒是可以实现,就是ajax方法会报错,虽然可以用,但是不够优雅;

由于开始一直在写博客后台,没考虑首页的问题,当我放弃使用拦截器以后,我把我的map放到了session中,这样登录以后肯定也是所有页面共享。再后来博客后台写的差不多了,准备开始写前台首页的时候发现这个方法也不对,总之这次自己写项目觉得不考虑清楚就写最后就会各种不对劲,就一直在改。

最终还是决定用Thymeleaf的自定义标签来解决这个问题。

一.html标签

<title thSys:text="'后台登录 - '"></title>

二.实现自定义标签处理器

新建一个java类 com.songhaozhi.mayday.config.thymeleaf.tag.ThSysTagProcessor.java

对于Thymeleaf方言,自定义标签的处理逻辑是在标签处理器定义的。

自定义标签处理器需要实现AbstractAttributeTagProcessor 接口,标签的处理逻辑在doProcess 方法中编写。

package com.songhaozhi.mayday.config.thymeleaf.tag;

import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.engine.AttributeName;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.AbstractAttributeTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.standard.expression.IStandardExpression;
import org.thymeleaf.standard.expression.IStandardExpressionParser;
import org.thymeleaf.standard.expression.StandardExpressions;
import org.thymeleaf.templatemode.TemplateMode;

import com.songhaozhi.mayday.model.dto.MaydayConst;

/**
*/
public class ThSysTagProcessor extends AbstractAttributeTagProcessor{
     private static final String TEXT_ATTRIBUTE  = "text";
     private static final int PRECEDENCE = 10000;
    /*templateMode: 模板模式,这里使用HTML模板。
     dialectPrefix: 标签前缀。即xxx:text中的xxx。在此例子中prefix为thSys。
     elementName:匹配标签元素名。举例来说如果是div,则我们的自定义标签只能用在div标签中。为null能够匹配所有的标签。
     prefixElementName: 标签名是否要求前缀。
     attributeName: 自定义标签属性名。这里为text。
     prefixAttributeName:属性名是否要求前缀,如果为true,Thymeeleaf会要求使用text属性时必须加上前缀,即thSys:text。
     precedence:标签处理的优先级,此处使用和Thymeleaf标准方言相同的优先级。
     removeAttribute:标签处理后是否移除自定义属性。*/
    public ThSysTagProcessor(String dialectPrefix) {
        super(
                TemplateMode.HTML, 
                dialectPrefix,     
                null,             
                false,             
                TEXT_ATTRIBUTE,         
                true,              
                PRECEDENCE,       
                true); 
    }

    @Override
    protected void doProcess(ITemplateContext context, IProcessableElementTag tag, AttributeName attributeName,
            String attributeValue, IElementTagStructureHandler structureHandler) {
         final IEngineConfiguration configuration = context.getConfiguration();
         final IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);
         final IStandardExpression expression = parser.parseExpression(context, attributeValue);
         final String title = (String) expression.execute(context);    
         structureHandler.setBody(title+MaydayConst.options.get("blog_name"),false);
    }

}

其中的MaydayConst.options.get(“blog_name”)是我数据库查出来缓存的map

三.定义方言类

package com.songhaozhi.mayday.config.thymeleaf.dialect;

import java.util.HashSet;
import java.util.Set;

import org.thymeleaf.dialect.AbstractProcessorDialect;
import org.thymeleaf.processor.IProcessor;
import org.thymeleaf.standard.StandardDialect;
import org.thymeleaf.standard.processor.StandardXmlNsTagProcessor;
import org.thymeleaf.templatemode.TemplateMode;

import com.songhaozhi.mayday.config.thymeleaf.tag.ThSysTagProcessor;

/**
 * 系统方言
* 
*/
public class ThSysDialect extends AbstractProcessorDialect{
    //定义方言名称
    private static final String DIALECT_NAME="Sys Dialect";
    
    public ThSysDialect() {
        //设置自定义方言与"方言处理器"优先级相同
        super(DIALECT_NAME, "thSys", StandardDialect.PROCESSOR_PRECEDENCE);
    }

    @Override
    public Set<IProcessor> getProcessors(String dialectPrefix) {
        Set<IProcessor> processors=new HashSet<IProcessor>();
        processors.add(new ThSysTagProcessor(dialectPrefix));
        processors.add(new StandardXmlNsTagProcessor(TemplateMode.HTML, dialectPrefix));
        return processors;
    }

}

四.在SpringBoot中加载自定义方言

com.songhaozhi.mayday.config.ThymeleafDialectConfig.java

package com.songhaozhi.mayday.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.songhaozhi.mayday.config.thymeleaf.dialect.ThSysDialect;

/**
 * Thymeleaf配置
* 
*/
@Configuration
public class ThymeleafDialectConfig {
    @Bean
    public ThSysDialect thSysDialect() {
        return new ThSysDialect();
    }
}

五.效果

其中”后台登录 – “是标签传递到后台的,”张三的博客”是数据库保存的值。

这就大功告成了!