Thymeleaf 长文本格式化、金额格式化

项目结构

Thymeleaf 长文本格式化、金额格式化_第1张图片
image.png

gradle注意事项

//    compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'

compile("org.thymeleaf:thymeleaf:3.0.6.RELEASE")

compile group:'org.thymeleaf',name:'thymeleaf-spring4',version:'3.0.6.RELEASE'

compile("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:2.2.2")

如果引用'spring-boot-starter-thymelea'将默认使用Thymeleaf2而不是3

代码


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.templateresolver.ITemplateResolver;


/**
 * Created by think on 2017/7/5.
 */
@Configuration
public class ThymeleafConfigure {

    @Bean
    public ITemplateResolver templateResolver() {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setTemplateMode("HTML5");
        templateResolver.setPrefix("classpath:/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setCharacterEncoding("utf-8");
        templateResolver.setOrder(1);
        templateResolver.setCacheable(false);
        templateResolver.setApplicationContext(UnionpayApplication.getApplicationContext()); //这里是你的自己的MIANf方法入口
        return templateResolver;
    }


    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.setTemplateResolver(templateResolver());
        engine.addDialect(new UnionPayDialect());
        return engine;
    }

}
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;

/**
 * Created by think on 2017/7/5.
 */
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 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 evaluateAsIterableOrRawValue(ITemplateContext arguments, String rawValue) {
        notNull(arguments, "arguments must not be null");
        notEmpty(rawValue, "rawValue must not be empty");

        final List result = new ArrayList();
        try {
            result.addAll(evaluateAsIterable(arguments, rawValue));
        } catch (TemplateProcessingException ex) {
            result.add(rawValue);
        }

        return unmodifiableList(result);
    }

    public static List 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 result = new ArrayList();
        final List iterates = evaluateAsIterableOrRawValue(arguments, rawValue);

        for (Object o : iterates) {
            result.addAll(asList(StringUtils.split(o, delimiter)));
        }

        return unmodifiableList(result);
    }
}
 
 
import org.thymeleaf.dialect.AbstractProcessorDialect;
import org.thymeleaf.processor.IProcessor;
import org.thymeleaf.standard.StandardDialect;

import java.util.HashSet;
import java.util.Set;

/**
 * Created by think on 2017/7/5.
 */
public class UnionPayDialect extends AbstractProcessorDialect {

    private static final String DIALECT_NAME = "UnionPay Dialect";


    public UnionPayDialect() {
        // We will set this dialect the same "dialect processor" precedence as
        // the Standard Dialect, so that processor executions can interleave.
        super(DIALECT_NAME, "unionpay", StandardDialect.PROCESSOR_PRECEDENCE);
    }

    @Override
    public Set getProcessors(String dialectPrefix) {
        final Set processors = new HashSet();
        processors.add(new UnionpayStringProcessor(dialectPrefix));
        processors.add(new UnionpayNumberProcessor(dialectPrefix));

        return processors;
    }
}
import org.apache.commons.lang3.StringUtils;
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 java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.List;

import static cn.gotoil.unionpay.config.thymeleaf.ThymeleafFacade.evaluateAsStringsWithDelimiter;
import static cn.gotoil.unionpay.config.thymeleaf.ThymeleafFacade.getRawValue;

/**
 * Created by think on 2017/7/5.
 */
public class UnionpayNumberProcessor extends AbstractAttributeTagProcessor {

    private static final String DELIMITER = ",";

    private static final String ATTR_NAME = "number";
    private static final int PRECEDENCE = 100;




    private static final String F2Y="moneyF2y"; //金额分转元保留2位小数

    public UnionpayNumberProcessor(final String dialectPrefix) {
        super(
                TemplateMode.HTML, // This processor will apply only to HTML mode
                dialectPrefix,     // Prefix to be applied to name for matching
                null,              // No tag name: match any tag name
                false,             // No prefix to be applied to tag name
                ATTR_NAME,         // Name of the attribute that will be matched
                true,              // Apply dialect prefix to attribute name
                PRECEDENCE,        // Precedence (inside dialect's own 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 method=null;
            String exper=null;
            if(StringUtils.isNotEmpty(rawValue)){
                method=rawValue.split(":")[0];  //获取类型
                exper=rawValue.split(":")[1]; //获取表达式
            }
            //通过IStandardExpression 解析器 解析表达式获取参数
            final List 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(F2Y.equalsIgnoreCase(method)){
                    try{
                        double n = NumberFormat.getInstance().parse(value).doubleValue();
                        model.add(modelFactory.createText(HtmlEscape.escapeHtml5(formatMoney(n))));
                    }catch (ParseException e){
                        model.add(modelFactory.createText(HtmlEscape.escapeHtml5("0")));
                    }

                }
            }
            //添加模型 标签
            model.add(modelFactory.createCloseElementTag(elementCompleteName));
            //替换页面标签
            structureHandler.replaceWith(model, false);
        }

    private String formatMoney(double value) {
        DecimalFormat df = new DecimalFormat("0.00");//格式化小数,不足的补0
        String v = df.format(value/100);//返回的是String类型的
        return v;
    }


}

import org.apache.commons.lang3.StringUtils;
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 java.util.List;

import static cn.gotoil.unionpay.config.thymeleaf.ThymeleafFacade.evaluateAsStringsWithDelimiter;
import static cn.gotoil.unionpay.config.thymeleaf.ThymeleafFacade.getRawValue;

/**
 * Created by think on 2017/7/5.
 */
public class UnionpayStringProcessor extends AbstractAttributeTagProcessor {

    private static final String DELIMITER = ",";

    private static final String ATTR_NAME = "string";
    private static final int PRECEDENCE = 100;


    private static final String LongTextFormat = "longTextFormat";
    private static final String CARD = "card";
    private static final String MOBILE = "mobile";
    private static final String IDENTITY = "identity";
    private static final String CSN = "csn";

    public UnionpayStringProcessor(final String dialectPrefix) {
        super(
                TemplateMode.HTML, // This processor will apply only to HTML mode
                dialectPrefix,     // Prefix to be applied to name for matching
                null,              // No tag name: match any tag name
                false,             // No prefix to be applied to tag name
                ATTR_NAME,         // Name of the attribute that will be matched
                true,              // Apply dialect prefix to attribute name
                PRECEDENCE,        // Precedence (inside dialect's own 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 method = null;
        String exper = null;
        if (StringUtils.isNotEmpty(rawValue)) {
            method = rawValue.split(":")[0];  //获取类型
            exper = rawValue.split(":")[1]; //获取表达式
        }
        //通过IStandardExpression 解析器 解析表达式获取参数
        final List 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(method)) {
                model.add(modelFactory.createText(HtmlEscape.escapeHtml5(getCardNo(value))));
            } else if (MOBILE.equals(method)) {
                model.add(modelFactory.createText(HtmlEscape.escapeHtml5(getMobile(value))));
            } else if (IDENTITY.equals(method)) {
                model.add(modelFactory.createText(HtmlEscape.escapeHtml5(getIdentity(value))));
            } else if (CSN.equals(method)) {
                model.add(modelFactory.createText(HtmlEscape.escapeHtml5(getCsn(value))));
            } else if (LongTextFormat.equals(method)) {
                int precLen = StringUtils.isEmpty(tag.getAttributeValue("prec")) ? 10 : Integer.parseInt(tag.getAttributeValue("prec"));
                model.add(modelFactory.createText(HtmlEscape.escapeHtml5(getLongTextFormat(value, precLen))));
            }
        }
        //添加模型 标签
        model.add(modelFactory.createCloseElementTag(elementCompleteName));
        //替换页面标签
        structureHandler.replaceWith(model, false);
    }

    private String getLongTextFormat(String value, int i) {
        if (StringUtils.isEmpty(value) || value.length() < i) {
            return value;
        } else {
            return value.substring(0, i) + "...";
        }
    }

    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 (StringUtils.isEmpty(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 (StringUtils.isEmpty(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 (StringUtils.isEmpty(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());
        }
    }

}

页面使用

//这里的prec 是指保留的长度 如果不设置也会有默认值

其他

  我这里是处理我自己的业务。希望能帮到大家。

你可能感兴趣的:(Thymeleaf 长文本格式化、金额格式化)