Thymeleaf 3.0 自定义标签方言属性的实例讲解

 更新时间:2020年09月18日 13:26:06   作者:Garc  
这篇文章主要介绍了Thymeleaf 3.0 自定义标签方言属性的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

此篇文章内容仅限于 描述 thy3.0 自定义标签的说明,所以你在看之前,请先会使用它。

直奔主题,以下代码是如何引用 第三方标签的。说明: shrioDialect 是Shiro 官方为thy开发的自定义标签工具。和jsp的一样

RiskDialect 是我写的自定义标签

 <bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
     <property name="templateResolver" ref="templateResolver"/>
     <property name="additionalDialects">
    <set>
      <!-- thymeleaf 使用shiro标签 -->
     <bean class="at.pollux.thymeleaf.shiro.dialect.ShiroDialect"/>
     <bean class="com.hpay.risk.boss.common.RiskDialect"/>
    </set>
  </property>
 </bean>

首先看代码:

import java.util.LinkedHashSet;
import java.util.Set; 
import org.thymeleaf.dialect.AbstractProcessorDialect;
import org.thymeleaf.processor.IProcessor;
import org.thymeleaf.standard.StandardDialect;
 
/**
 *@author Garc
 *@Date 2017年2月16日 上午11:42:51
 *@info thymeleaf 自定义标签属性
 *@snise
 **/
public class RiskDialect extends AbstractProcessorDialect {
 
  private static final String NAME = "Risk";
  private static final String PREFIX = "risk";
 
  public RiskDialect() {
    super(NAME, PREFIX, StandardDialect.PROCESSOR_PRECEDENCE);
  }
 
 @Override
 public Set<IProcessor> getProcessors(String dialectPrefix) {
 return createStandardProcessorsSet(dialectPrefix);
 }
 
 private Set<IProcessor> createStandardProcessorsSet(String dialectPrefix) {
 LinkedHashSet<IProcessor> processors = new LinkedHashSet<IProcessor>();
 processors.add(new SansitiveEncryptProcessor(dialectPrefix));
 return processors;
 }
 
}

我定义了 RiskDialect 类,并需要继承 thymeleaf 官方 方言类

我定义的这个是为了做敏感数据加密用的。 这是前段代码。

以下是实现自定义标签方言 代码:

import static at.pollux.thymeleaf.shiro.processor.ThymeleafFacade.evaluateAsStringsWithDelimiter;
import static at.pollux.thymeleaf.shiro.processor.ThymeleafFacade.getRawValue;
 
import java.util.List; 
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.engine.AttributeName;
import org.thymeleaf.model.IModel;
import org.thymeleaf.model.IModelFactory;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.AbstractAttributeTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.templatemode.TemplateMode;
import org.unbescape.html.HtmlEscape;
 
import com.hpay.utils.StringUtils;
 
/**
 *@author Garc
 *@Date 2017年2月16日 上午11:48:34
 *@info 敏感加密标签
 *@snise
 **/
public class SansitiveEncryptProcessor extends AbstractAttributeTagProcessor{
 
  private static final String DELIMITER = ",";
  private static final String ATTRIBUTE_NAME = "sansiEncrypt";
  private static final int PRECEDENCE = 300;
  
  private static final String CARD="card";
  private static final String MOBILE="mobile";
  private static final String IDENTITY="identity";
  private static final String CSN="csn";
  
 protected SansitiveEncryptProcessor( String dialectPrefix) {
 super(
        TemplateMode.HTML, // 处理thymeleaf 的模型
        dialectPrefix, // 标签前缀名
        null, // No tag name: match any tag name
        false, // No prefix to be applied to tag name
        ATTRIBUTE_NAME, // 标签前缀的 属性 例如:< risk:sansiEncrypt="">
        true, // Apply dialect prefix to attribute name
        PRECEDENCE, // Precedence (inside dialect's precedence)
        true); // Remove the matched attribute afterwards
    }
 
 @Override
 protected void doProcess(ITemplateContext context,
  IProcessableElementTag tag, AttributeName attributeName,
  String attributeValue, IElementTagStructureHandler structureHandler) {
 
        final String rawValue = getRawValue(tag, attributeName); //获取标签内容表达式
 String type=null;
 String exper=null;
 if(StringUtils.isNotBlank(rawValue)){
  type=rawValue.split(":")[0]; //获取类型
  exper=rawValue.split(":")[1]; //获取表达式
 }
 //通过IStandardExpression 解析器 解析表达式获取参数
     final List<String> values = evaluateAsStringsWithDelimiter(context, exper, DELIMITER);
     final String elementCompleteName = tag.getElementCompleteName(); //标签名
     //创建模型
     final IModelFactory modelFactory = context.getModelFactory();
     final IModel model = modelFactory.createModel();
     //添加模型 标签
     model.add(modelFactory.createOpenElementTag(elementCompleteName));
     for (String value : values) {
     //创建 html5标签 文本返回数据
     if(CARD.equals(type)){
      model.add(modelFactory.createText(HtmlEscape.escapeHtml5(getCardNo(value))));
     }else if(MOBILE.equals(type)){
      model.add(modelFactory.createText(HtmlEscape.escapeHtml5(getMobile(value))));
     }else if(IDENTITY.equals(type)){
      model.add(modelFactory.createText(HtmlEscape.escapeHtml5(getIdentity(value))));
     }else if(CSN.equals(type)){
      model.add(modelFactory.createText(HtmlEscape.escapeHtml5(getCsn(value))));
     }
  }
     //添加模型 标签
     model.add(modelFactory.createCloseElementTag(elementCompleteName));
     //替换页面标签
     structureHandler.replaceWith(model, false);
 }
 
 protected String getCardNo(String cardNo) {
 if (StringUtils.isNotBlank(cardNo) && cardNo.length() >= 9) {
  return cardNo.substring(0, 4) + cardNo.substring(4, cardNo.length() - 3).replaceAll("[0-9]", "*") + cardNo.substring(cardNo.length() - 4, cardNo.length());
 }
 return cardNo;
 }
  
    protected static String getIdentity(String val){
       if(org.apache.commons.lang.StringUtils.isBlank(val)||val.length()<9){
 return val;
     }else{
     return val.substring(0, 4)+ val.substring(4, val.length()-4).replaceAll("[0-9]", "*") + val.substring(val.length()-4, val.length());
     }
    }
  /**
   * 前四后四显示
   * @param val
   * @return
   */
  protected static String getMobile(String val){
 if(org.apache.commons.lang.StringUtils.isBlank(val)||val.length()<9){
  return val;
   }else{
   return val.substring(0, 3)+ val.substring(4, val.length()-3).replaceAll("[0-9]", "*") + val.substring(val.length()-4, val.length());
   }
 }
  /**
   * 星星显示
   * @param val
   * @return
   */
  protected String getCsn(String val){
 if(org.apache.commons.lang.StringUtils.isBlank(val)||val.length()<12){
   return val;
   }else{
   return val.substring(0, 2)+ val.substring(2, val.length()-3).replaceAll("[0-9a-zA-Z]", "*") + val.substring(val.length()-6, val.length());
   }
   }
}

以下代码是为了向SansitiveEncryptProcessor 提供的解析表达式 thymeleaf解析器,用来获取参数值的:

import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.engine.AttributeName;
import org.thymeleaf.exceptions.TemplateProcessingException;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.standard.expression.IStandardExpression;
import org.thymeleaf.standard.expression.IStandardExpressionParser;
import org.thymeleaf.standard.expression.StandardExpressionParser;
import org.thymeleaf.util.EvaluationUtils;
import org.thymeleaf.util.StringUtils;
 
import java.util.ArrayList;
import java.util.List;
 
import static java.util.Arrays.asList;
import static java.util.Collections.unmodifiableList;
import static org.thymeleaf.util.StringUtils.trim;
import static org.thymeleaf.util.Validate.notEmpty;
import static org.thymeleaf.util.Validate.notNull;
 
public final class ThymeleafFacade {
 
  private ThymeleafFacade() {
    throw new UnsupportedOperationException();
  }
 
  public static String getRawValue(final IProcessableElementTag element, final AttributeName attributeName) {
    notNull(element, "element must not be null");
    notNull(attributeName, "attributeName must not be empty");
 
    final String rawValue = trim(element.getAttributeValue(attributeName));
    notEmpty(rawValue, "value of '" + attributeName + "' must not be empty");
 
    return rawValue;
  }
 
  public static String getRawValue(final IProcessableElementTag element, final String attributeName) {
    notNull(element, "element must not be null");
    notEmpty(attributeName, "attributeName must not be empty");
 
    final String rawValue = trim(element.getAttributeValue(attributeName));
    notEmpty(rawValue, "value of '" + attributeName + "' must not be empty");
 
    return rawValue;
  }
 
  public static Object evaluateExpression(ITemplateContext arguments, String expression) throws TemplateProcessingException {
    notNull(arguments, "arguments must not be null");
    notEmpty(expression, "expression must not be empty");
 
    final IStandardExpressionParser parser = new StandardExpressionParser();
 
    final IStandardExpression evaluableExpression = parser.parseExpression(arguments, expression);
 
    return evaluableExpression.execute(arguments);
  }
 
  public static List<Object> evaluateAsIterable(ITemplateContext arguments, String rawValue) throws TemplateProcessingException {
    notNull(arguments, "arguments must not be null");
    notEmpty(rawValue, "rawValue must not be empty");
 
    final Object evaluatedExpression = evaluateExpression(arguments, rawValue);
 
    return EvaluationUtils.evaluateAsList(evaluatedExpression);
  }
 
  public static List<Object> evaluateAsIterableOrRawValue(ITemplateContext arguments, String rawValue) {
    notNull(arguments, "arguments must not be null");
    notEmpty(rawValue, "rawValue must not be empty");
 
    final List<Object> result = new ArrayList<Object>();
    try {
      result.addAll(evaluateAsIterable(arguments, rawValue));
    } catch (TemplateProcessingException ex) {
      result.add(rawValue);
    }
 
    return unmodifiableList(result);
  }
 
  public static List<String> evaluateAsStringsWithDelimiter(ITemplateContext arguments, String rawValue, String delimiter) {
    notNull(arguments, "arguments must not be null");
    notEmpty(rawValue, "rawValue must not be empty");
    notEmpty(delimiter, "delimiter must not be empty");
 
    final List<String> result = new ArrayList<String>();
    final List<Object> iterates = evaluateAsIterableOrRawValue(arguments, rawValue);
 
    for (Object o : iterates) {
      result.addAll(asList(StringUtils.split(o, delimiter)));
    }
 
    return unmodifiableList(result);
  }

以上为 后端代码实现内容,

页面标签使用方式:

<td risk:sansiEncrypt="card:${data.payerCardNo}"></td>

card 是需要 加密的类型,我实现的代码里 对身份证和 手机号还有 CSN 加了密。

上面的内容讲的是 标签传入数据 并返回处理数据。

类似于 if 的标签属性,就不写了。

以上这篇Thymeleaf 3.0 自定义标签方言属性的实例讲解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java中的CountDownLatch原理深入解析

    Java中的CountDownLatch原理深入解析

    这篇文章主要介绍了Java中的CountDownLatch原理深入解析,CountDownLatch是多线程控制的一种同步工具类,它被称为门阀、 计数器或者闭锁,这个工具经常用来用来协调多个线程之间的同步,或者说起到线程之间的通信,需要的朋友可以参考下
    2024-01-01
  • 详谈JSON与Javabean转换的几种形式

    详谈JSON与Javabean转换的几种形式

    下面小编就为大家带来一篇详谈JSON与Javabean转换的几种形式。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • Mac Maven环境搭建安装和配置超详细步骤

    Mac Maven环境搭建安装和配置超详细步骤

    这篇文章主要给大家介绍了关于Mac Maven环境搭建安装和配置的超详细步骤,Maven是一种常用的Java构建工具,它可以自动化构建、测试和打包Java项目,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • Java和c语言随机数Random代码详细

    Java和c语言随机数Random代码详细

    这篇文章主要介绍Java和c语言得随机数Random,随机数的用处在生活中比较少见,但是用处并不少,比如一些小游戏的制作等等。下面我们就一起来学习这篇关于Java和c随机数Random得文章吧
    2021-10-10
  • 详解Java8如何使用Lambda表达式进行比较

    详解Java8如何使用Lambda表达式进行比较

    Lambda表达式,也可称为闭包,是java8的新特性,作用是取代大部分内部类,优化java代码结构,让代码变得更加简洁紧凑。本文将利用Lambda表达式进行排序比较,需要的可以参考一下
    2022-01-01
  • Java中比较抽象类与接口的异同

    Java中比较抽象类与接口的异同

    大家好,本篇文章主要讲的是Java中比较抽象类与接口的异同,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • MapStruct表达式应用及避坑详解

    MapStruct表达式应用及避坑详解

    一不小心踩了MapStruct表达式的坑,发现了一个在官方文档上都找不到的功能,有必要记录下。MapStruct是一个代码生成器,它基于约定优于配置的方法大大简化了Java Bean类型之间的映射的实现
    2022-02-02
  • Java设计模式之单一职责原则精解

    Java设计模式之单一职责原则精解

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。本篇介绍设计模式七大原则之一的单一职责原则
    2022-02-02
  • java中List<对象>如何根据对象的一个属性进行去重

    java中List<对象>如何根据对象的一个属性进行去重

    这篇文章主要给大家介绍了关于java中List<对象>如何根据对象的一个属性进行去重的相关资料,在开发中可能会遇到很多需要去重的情况,比如Person对象有name跟age两个属性,需要根据age进行去重,需要的朋友可以参考下
    2023-08-08
  • java中驼峰与下划线的写法互转

    java中驼峰与下划线的写法互转

    这篇文章主要介绍了java中驼峰与下横线的写法互转方法,文中先是进行了简单的介绍,之后跟大家分享了一个自己编写的工具类的示例代码,有需要的朋友可以参考借鉴,下面来一起学习学习吧。
    2017-01-01

最新评论