thymeleaf+Springboot实现自定义标签

在项目开发中,有一些组件不能满足我们快速开发的要求,我们需要封装一些组件来更加的便利我们。比如,我们可以封装一个下拉框组件,只要开发人员只有引用这个组件的标签,就能出现效果,而不用再去请求url,渲染等等。以下我们以一个select下拉组件为例

1、我们先自定义一个类:MqInputTagProcessor  并继承了AbstractElementTagProcessor父类

package com.www.baidu.com.web.tag.processor;

import org.apache.commons.lang.StringUtils;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.exceptions.TemplateProcessingException;
import org.thymeleaf.model.IModel;
import org.thymeleaf.model.IModelFactory;
import org.thymeleaf.model.IOpenElementTag;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.AbstractElementTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.standard.expression.IStandardExpression;
import org.thymeleaf.standard.expression.IStandardExpressionParser;
import org.thymeleaf.standard.expression.StandardExpressionParser;
import org.thymeleaf.templatemode.TemplateMode;

import java.util.HashMap;
import java.util.Map;

public class MqInputTagProcessor extends AbstractElementTagProcessor
{

private final static String TAG_NAME = "definitionSelect";
private final static int PRECEDENCE = 9999;

/**
* Description:
* @param dialectPrefix
*/
public MqInputTagProcessor(String dialectPrefix)
{
super(TemplateMode.HTML, // 模板类型
dialectPrefix, // 要应用于名称的匹配前缀
TAG_NAME, // 标签名称
true, // 将标签前缀应用于标签名称
null, // 无属性名称:将通过标签名称匹配
false, // 没有要应用于属性名称的前缀
PRECEDENCE // 优先级
        );

}

@Override
protected void doProcess(ITemplateContext context, IProcessableElementTag tag,
IElementTagStructureHandler structureHandler)
{
// 获取我们html中封装的标签上的各个属性值,也可以用tag.getAttributeMap()来获取
String mqNameValue = tag.getAttributeValue("name");
String mqValue = tag.getAttributeValue("value");
String mqId = tag.getAttributeValue("id");
String mqClass = tag.getAttributeValue("class");
String mqStyle = tag.getAttributeValue("style");
String value = evaluateExpression(context, mqValue) + "";
IModelFactory modelFactory = context.getModelFactory();

     // 模拟从数据库中获取的数据
Map<String, String> strMap = new HashMap<>(16);
strMap.put("zhangsan", "张三");
strMap.put("lisi", "李四");
strMap.put("wangwu", "王五");
strMap.put("zhaoliu", "赵六");

// 创建IModel对象
     IModel model = modelFactory.createModel();
     // 获得IOpenElementTag对象来构建标签模板

IOpenElementTag openElementTag = modelFactory.createOpenElementTag("select", "class", mqClass);
openElementTag = modelFactory.setAttribute(openElementTag, "style", mqStyle);
openElementTag = modelFactory.setAttribute(openElementTag, "id", mqId);
openElementTag = modelFactory.setAttribute(openElementTag, "value", value);
openElementTag = modelFactory.setAttribute(openElementTag, "name", mqNameValue);
     // 把IOpenElementTag对象构建的标签模板放入model中
model.add(openElementTag);
// 构建select下的option标签
     model.add(modelFactory.createOpenElementTag("option value=''"));

model.add(modelFactory.createText("选择类别"));
     // 构建结束标签

model.add(modelFactory.createCloseElementTag("option"));

// 创建option
strMap.forEach((k, v) -> {
IOpenElementTag openElementTag1 = modelFactory.createOpenElementTag(String.format("option value='%s'", k));
if (k.equals(value))
{
openElementTag1 = modelFactory.setAttribute(openElementTag1, "selected", "true");
}
model.add(openElementTag1);
model.add(modelFactory.createText(v));
model.add(modelFactory.createCloseElementTag("option"));
modelFactory.createOpenElementTag("option");
});

model.add(modelFactory.createCloseElementTag("select"));
  
// 指示引擎用指定的模板替换整个元素
     structureHandler.replaceWith(model, false);

}

private Object evaluateExpression(ITemplateContext context, String expression) throws TemplateProcessingException
{
if (StringUtils.isEmpty(expression))
{
return null;
}
final IStandardExpressionParser parser = new StandardExpressionParser();

final IStandardExpression evaluableExpression = parser.parseExpression(context, expression);

return evaluableExpression.execute(context);
}
}

2、定义方言

package com.xxxx.web.tag.dialect;

import com.skywares.web.tag.processor.*;
import org.thymeleaf.dialect.AbstractProcessorDialect;
import org.thymeleaf.processor.IProcessor;

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

public class StDialect extends AbstractProcessorDialect
{
    private static final int PROCESSOR_PRECEDENCE = 1000;// 方言(标签)优先级
    private static final String DIALECT_NAME = "ai Dialect";// 方言(标签)名称
    private static final String PREFIX = "ai";// 方言(标签)前缀

    protected StDialect(String name, String prefix, int processorPrecedence)
    
        super(name, prefix, processorPrecedence);
    }

    public StDialect()
    {
        // 我们将设置此方言与“方言处理器”优先级相同
        // 标准方言, 以便处理器执行交错。
        super(DIALECT_NAME, PREFIX, PROCESSOR_PRECEDENCE);
    }

    /**
     * 注册标签
     */
    @Override
    public Set<IProcessor> getProcessors(String dialectPrefix)
    {
        return createStandardProcessorsSet(dialectPrefix);
    }
    
    public static Set<IProcessor> createStandardProcessorsSet(final String dialectPrefix)
    {
        Set<IProcessor> processors = new HashSet<IProcessor>();
        processors.add(new DefinitionsSelectTagProcessor(dialectPrefix));
        return processors;
    }
}

3、界面上的使用:

// qo为回显的Map集合,itemId为key
<ai:definitionSelect id="oidjf" name="stuNo" th:value="{qo['stuNo']}" />

4、实现的效果:

 

 

 

 

posted @ 2020-03-18 18:20  Aj小菜  阅读(1365)  评论(0编辑  收藏  举报