在项目开发中,有一些组件不能满足我们快速开发的要求,我们需要封装一些组件来更加的便利我们。比如,我们可以封装一个下拉框组件,只要开发人员只有引用这个组件的标签,就能出现效果,而不用再去请求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、实现的效果:

thymeleaf+Springboot实现自定义标签的更多相关文章

  1. spring thymeleaf 自定义标签

    概述 thymeleaf2.1.5自定义标签及自定义属性案例,类似于JSP中的自定义JSTL标签 详细 代码下载:http://www.demodashi.com/demo/10495.html 一. ...

  2. thymeleaf教程-springboot项目中实现thymeleaf自定义标签

    转载: http://www.9191boke.com/466119140.html    91博客网 开始: 在使用thymeleaf的过程中有时候需要公共部分渲染页面,这个时候使用自定义标签实现自 ...

  3. thymeleaf自定义标签方言处理

    项目背景:springboot+thymeleaf thymeleaf两种方式处理自定义标签:AbstractAttributeTagProcessor 和 AbstractElementTagPro ...

  4. Java Spring Boot VS .NetCore (十一)自定义标签 Java Tag Freemarker VS .NetCore Tag TagHelper

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...

  5. spring Cache + Redis 开发数据字典以及自定义标签

    一.数据库表结构 1.  分类表:dict_type 2.  子项表:dict_entry 二.页面维护功能示意图: 1.  分类管理 点击子项管理进入子项管理页面 2.子项管理 三.数据字典添加到缓 ...

  6. OneBlog开源博客-详细介绍如何实现freemarker自定义标签

    前言 OneBlog中使用到了springboot + freemarker的技术,同时项目里多个controller中都需要查询一个公有的数据集合,一般做法是直接在每个controller的方法中通 ...

  7. [JSP]自定义标签库taglib

    自定义标签的步骤 自定义标签的步骤大概有三步: 1.继承javax.servlet.jsp.tagext.*下提供的几个标签类,如Tag.TagSupport.BodyTagSupport.Simpl ...

  8. [Java] JSP笔记 - 自定义标签

    自定义标签的创建步骤: 自定义标签的四大功能: 自定义标签的类结构: 在 1.0 中呢, 可以将 <body-content> 的值设置为 JSP, 2.0中则不允许在自定义标签体中出现j ...

  9. thinkphp自定义标签库

    thinkphp ~ php中 的类, 的成员变量, 本身是没有类型说明的, 那么我怎么知道它的类型呢? 或初始值呢? 通常在类定义中, 如果能给一个初始值的(对于已知简单类型的),最好给一个初始值, ...

随机推荐

  1. UVA10391复合词

    题意:      给定一个词典,然后问里面那些是复合词,复合词就是当前这个单词正好是有两个单词拼接而成. 思路:       用map来标记是否出现过,然后先按长短排序,把每个单体拆分成任意两个可能的 ...

  2. 【vue-01】快速入门

    什么是vue vue是渐进式的JavaScript框架 什么是渐进式? ​ 你可以在原有大系统的上面,把一两个组件改用vue实现,:也可以整个项目用vue全家桶开发. ​ vue是一个轻量级的MVVM ...

  3. 一、Github+Pycharm基础

    GitHub为版本管理工具 常用的版本管理工具:本地化版本管理系统.集中式版本管理系统SVN.分布式版本管理系统 一.安装git(自行百度) 二.文件操作与分支管理基础 1.版本控制系统分类 集中化版 ...

  4. C++ scanf_s()函数的用法以及注意事项

    前身--scanf() 有的教材里用的scanf(),其实在目前Visual Studio版本中已经弃用了,用scanf_s()函数代替了. 为什么现在要用scanf_s() scanf_s()函数是 ...

  5. FFmpeg应用实践之命令查询

    0. 前言 FFmpeg 中常用的工具有三个,分别是多媒体编解码工具ffmpeg.多媒体内容分析工具ffprobe和多媒体播放器ffplay.本文介绍的指令都是与编解码工具 ffmpeg 相关的. 学 ...

  6. Let's go!

    第一次开通博客 心情还是很激动的,而且做出了这么好看的页面虽然都是用的别人的组件,自己不是很知道原理但是也很开心,以后会将自己学习的东西写成笔记发在上面

  7. [Java]数据分析--聚类

    距离度量 需求:计算两点间的欧几里得距离.曼哈顿距离.切比雪夫距离.堪培拉距离 实现:利用commons.math3库相应函数 1 import org.apache.commons.math3.ml ...

  8. [bug] IDEA springboot项目 访问静态资源 html页面 报404

    原因 复制的静态资源目录没有编译 解决 检查target目录中,是否有static目录,若没有,重新右键项目install即可 若还不能解决,尝试浏览器缓存和IDEA编译设置,详见参考链接 参考 ht ...

  9. 【BIGDATA】Grafana告警之webhook的坑

    近日搭建一套基于ELK&Grafana的监控告警平台,目的是将生产端某性能日志导入ES中,通过Grafana进行可视化监测,同时设置告警. 告警内容推送到自建的webhook服务后,转发到指定 ...

  10. 安装SpecCPU2006 on Linux of CentOS6.3, gcc4.4.7

    安装SpecCPU2006 on Linux of CentOS6.3, gcc4.4.7 由于在tools/bin目录中只有ia64-linux,所以在直接运行./install.sh脚本时,系统会 ...