You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Thymeleaf模板中自动高亮动态值?

实现Thymeleaf动态输出值的高亮包裹

可以实现这个需求,核心思路是在变量输出阶段对值进行包裹,同时保留模板中条件判断的原始变量引用,以下是两种可行方案:

方案一:自定义表达式工具类(手动包裹,灵活可控)

  1. 编写工具类,提供高亮包裹方法:
public class HighlightUtils {
    public static String highlight(Object value) {
        if (value == null) {
            return "";
        }
        return "<span style='background-color: yellow;'>" + value.toString() + "</span>";
    }
}
  1. 将工具类注册为Thymeleaf表达式对象,让模板可直接调用:
import org.thymeleaf.context.IExpressionContext;
import org.thymeleaf.expression.IExpressionObjectFactory;
import java.util.Collections;
import java.util.Set;

public class HighlightExpressionObjectFactory implements IExpressionObjectFactory {
    public static final String HL_OBJECT_NAME = "hl";

    @Override
    public Set<String> getAllExpressionObjectNames() {
        return Collections.singleton(HL_OBJECT_NAME);
    }

    @Override
    public Object buildObject(IExpressionContext context, String name) {
        if (HL_OBJECT_NAME.equals(name)) {
            return new HighlightUtils();
        }
        return null;
    }

    @Override
    public boolean isCacheable(String name) {
        return HL_OBJECT_NAME.equals(name);
    }
}
  1. 在Spring配置中注册表达式对象工厂:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;

@Configuration
public class ThymeleafConfig {
    @Bean
    public SpringTemplateEngine templateEngine(SpringResourceTemplateResolver resolver) {
        SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.setTemplateResolver(resolver);
        engine.addExpressionObjectFactory(new HighlightExpressionObjectFactory());
        return engine;
    }
}
  1. 修改模板,仅在输出时调用高亮方法,条件判断保留原始变量:
<div th:if="${a} == 'a'" th:text="'hello ' + ${#hl.highlight(a)}?${#hl.highlight(b)}:${#hl.highlight(c)}">

这种方式不会影响条件判断逻辑,且能精准控制哪些变量需要高亮。

方案二:自定义处理器(自动包裹,无需修改模板)

如果不想手动修改模板,可以通过自定义Thymeleaf处理器,自动拦截th:text/th:utext属性,修改其表达式为自动包裹变量的形式:

  1. 编写处理器类处理th:text:
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.engine.AttributeName;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.AbstractAttributeTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.templatemode.TemplateMode;

public class HighlightTextProcessor extends AbstractAttributeTagProcessor {
    private static final String ATTR_NAME = "text";
    private static final int PRECEDENCE = 1000;

    public HighlightTextProcessor(String dialectPrefix) {
        super(TemplateMode.HTML, dialectPrefix, null, false, ATTR_NAME, true, PRECEDENCE, true);
    }

    @Override
    protected void doProcess(ITemplateContext context, IProcessableElementTag tag, AttributeName attrName, String attrValue, IElementTagStructureHandler handler) {
        // 替换表达式中的变量引用为高亮包裹形式(简单正则,复杂表达式需用表达式解析器)
        String processedExpr = attrValue.replaceAll("\\$\\{([^}]+)\\}", "\\${#hl.highlight($1)}");
        handler.setAttribute(attrName, processedExpr);
    }
}
  1. 编写自定义方言并注册处理器(需同时实现HighlightUTextProcessor处理th:utext):
import org.thymeleaf.dialect.AbstractProcessorDialect;
import org.thymeleaf.processor.IProcessor;
import java.util.HashSet;
import java.util.Set;

public class HighlightDialect extends AbstractProcessorDialect {
    public static final String NAME = "Highlight Dialect";
    public static final String PREFIX = "hl";
    public static final int PROCESSOR_PRECEDENCE = 1000;

    public HighlightDialect() {
        super(NAME, PREFIX, PROCESSOR_PRECEDENCE);
    }

    @Override
    public Set<IProcessor> getProcessors(String prefix) {
        Set<IProcessor> processors = new HashSet<>();
        processors.add(new HighlightTextProcessor(prefix));
        processors.add(new HighlightUTextProcessor(prefix));
        return processors;
    }
}
  1. 在Spring配置中注册方言和表达式对象工厂(同方案一):
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;

@Configuration
public class ThymeleafConfig {
    @Bean
    public SpringTemplateEngine templateEngine(SpringResourceTemplateResolver resolver) {
        SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.setTemplateResolver(resolver);
        engine.addDialect(new HighlightDialect());
        engine.addExpressionObjectFactory(new HighlightExpressionObjectFactory());
        return engine;
    }
}
  1. 模板无需修改,处理器会自动将th:text中的变量替换为高亮包裹形式,条件判断不受影响。

注意事项

  • 简单正则替换可能无法处理复杂表达式(如嵌套表达式、方法调用),若需支持复杂场景,需使用Thymeleaf的表达式解析器遍历表达式树进行修改。
  • 如果使用th:utext,需确保高亮后的HTML不会被转义,工具类中的输出无需额外处理,因为th:utext会直接渲染HTML。

内容的提问来源于stack exchange,提问作者Cardinal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 08:50:59