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

作者:Garc 时间:2023-03-24 20:40:23 

此篇文章内容仅限于 描述 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);
 }

来源:https://blog.csdn.net/Qensq/article/details/55258104

标签:Thymeleaf,3.0,标签,方言
0
投稿

猜你喜欢

  • 浅谈Java自定义类加载器及JVM自带的类加载器之间的交互关系

    2021-09-12 23:37:24
  • Java 入门图形用户界面设计之复选框

    2022-06-19 15:22:53
  • 使用idea2017搭建SSM框架(图文步骤)

    2023-04-30 15:28:59
  • PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例

    2023-11-26 15:05:59
  • Android操作系统的架构设计分析

    2022-07-12 11:02:26
  • Android下拉刷新控件SwipeRefreshLayout源码解析

    2023-04-03 20:42:16
  • Kotlin基础通关之字符串与数字类型

    2023-06-22 13:27:35
  • IntelliJ IDEA maven 构建简单springmvc项目(图文教程)

    2021-09-13 05:40:40
  • Java实现AOP面向切面编程的实例教程

    2023-02-20 19:32:38
  • 将15位身份证补全为18位身份证的算法示例详解

    2022-07-15 19:33:43
  • 经典实例讲解C#递归算法

    2022-04-11 22:34:16
  • WPF实现页面的切换的示例代码

    2023-09-26 21:35:27
  • spring多数据源配置实现方法实例分析

    2023-06-06 22:15:56
  • C#适配器模式的使用

    2022-02-05 15:47:21
  • Android7.0行为变更之适配File Provider的方法

    2021-09-24 08:02:38
  • java基础的详细了解第八天

    2023-11-08 10:47:47
  • Java实现人机猜拳小游戏

    2023-10-07 16:11:37
  • 利用Java8 Optional类优雅如何地解决空指针问题

    2023-07-30 04:58:13
  • Unity shader实现遮罩效果

    2023-06-28 10:20:09
  • C#中怎么将一个List转换为只读的

    2021-10-04 15:52:51
  • asp之家 软件编程 m.aspxhome.com