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

    线程局部存储(TLS) 这个东西并不陌生了,之前写过了一个关于这个的应用,利用静态TLS姿势实现代码段静态加密免杀或者所谓的加壳思路.地址在这:http://blog.csdn.net/u013761 ...

  2. java之I/O流

    I/O流的使用情况多种多样,首先它的数据源就可能是文件.控制台.服务器等,它的单位可能是按字节.按字符.按行等.为了涵盖所有的可能,java类库中创建了大量的类,如此多的类让我们在使用时感觉有点难以选 ...

  3. Nginx解决跨域问题(CORS)

    跨域 解决跨域问题一般有两种思路: CORS 在后端服务器设置 HTTP 响应头,把你需要运行访问的域名加入加入 Access-Control-Allow-Origin中. jsonp 把后端根据请求 ...

  4. 逆向工程初步160个crackme-------6

    工具:1. 按钮事件地址转换器E2A 2. PEID 3. Ollydbg 同样我们先来运行一下这个程序, ok按钮是被禁用的,有一个help按钮点击后弹出一个消息框:消息框显示提示信息为.本程序需要 ...

  5. (转)elasticsearch连接不到head插件解决方案

    (1)elasticsearch-5x下的 config/elasticsearch.yml   http.cors.enabled: true   http.cors.allow-origin: & ...

  6. Solon Aop 特色开发(1)注入或手动获取配置

    常规操作,先启动 Solon public class App{ public void main(String[] args){ Solon.start(App.class, args); } } ...

  7. linux-TCP多线程的并发服务器- 以言责人甚易,以义持己实难!!!

    1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <ti ...

  8. Jekyll+GitHub Pages部署自己的静态Blog

    混了这么久,一直想拥有自己的博客,通过jekyll和GitHub Pages捣腾出了自己的博客(https://www.ichochy.com) 一.安装jekyll 首先有安装Ruby的开发环境 运 ...

  9. Envoy:TLS双向认证

    环境准备 主机 角色 数量 front-envoy front envoy 1 service envoy 作为内部后端的envoy 2 end 后端应用程序 2 访问 / front-envoy = ...

  10. vim使用基础

    vi/vim编辑器使用 前言 There is an old joke about a visitor to New York City asking a passerby for direction ...