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 的标签属性,就不写了,由于在上班,就写这么多,如果想了解更多,可以加QQ群 119170668:亲自找我,我为你指导。群主就是我!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Qensq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值