Springboot2.x + thymeleaf自定义标签

Springboot2.x + thymeleaf自定义标签

版本

  • springboot 2.x
  • maven
  • spring-boot-starter-thymeleaf
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

前端的标签

<smlai:select dicType="all" data-placeholder="选择类别" class="form-control chosen-select"
                                     tabindex="2" style="width: 100%">
                            <option value="">选择类别</option>
</smlai:select>

自定义标签注入类

  • IftgDialectEntrance
    import org.springframework.stereotype.Component;
    import org.thymeleaf.dialect.AbstractProcessorDialect;
    import org.thymeleaf.dialect.IProcessorDialect;
    import org.thymeleaf.processor.IProcessor;
    import org.thymeleaf.standard.StandardDialect;
    
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * 自定注解处理入口
     */
    @Component
    public class IftgDialectEntrance extends AbstractProcessorDialect implements IProcessorDialect {
    
        private static final String DIALECT_NAME = "samlai-dialect";
    
        private static final String PREFIX = "smlai";
    
        public IftgDialectEntrance() {
            super(DIALECT_NAME, PREFIX, StandardDialect.PROCESSOR_PRECEDENCE);
        }
    
        @Override
        public Set<IProcessor> getProcessors(String dialectPrefix) {
            Set<IProcessor> processors = new HashSet<IProcessor>();
            processors.add(new IftgSelectProcessor(PREFIX));
            return processors;
        }
    }
    

自定义标签逻辑类

  • IftgSelectProcessor
     import java.util.List;
     
     import com.sml.service.sys.DictService;
     import com.sml.utils.IftgUtil;
     import com.sml.vo.ValueVO;
     import org.apache.commons.lang3.StringUtils;
     import org.springframework.context.ApplicationContext;
     import org.thymeleaf.context.ITemplateContext;
     import org.thymeleaf.model.IModel;
     import org.thymeleaf.model.IModelFactory;
     import org.thymeleaf.model.IOpenElementTag;
     import org.thymeleaf.model.IProcessableElementTag;
     import org.thymeleaf.processor.element.AbstractElementTagProcessor;
     import org.thymeleaf.processor.element.IElementTagStructureHandler;
     import org.thymeleaf.spring5.context.SpringContextUtils;
     import org.thymeleaf.templatemode.TemplateMode;
     
     /**
      * select 注解 用法 <smlai:select dicType = "dic_of_sex"></smlai:select> 属性
      * dicType是必填项 --情况1:当dicType = 字典中的type 时select下拉数值渲染的value 为字典中的name字段,name
      * 为字典中的name字段
      *
      *
      * --情况2:当dicType = all时候表示select下拉数值渲染的value 为字典中的type字段,name
      * 为字典中的description字段)
      *
      * 注: 控件的其他属性,用户可根据需求完全自定义,如需要加上name属性和Id属性则
      * <smlai:select dicType = "dic_of_sex" name="mySelect" id=
      * "selectId"></smlai:select>
      */
     
     public class IftgSelectProcessor extends AbstractElementTagProcessor {
     
         private DictService dictService;
     
         private boolean firstLoad = true;
     
         private static final String ATTR_NAME = "select";
         private static final int PRECEDENCE = 120;
     
         public IftgSelectProcessor(final String dialectPrefix) {
     
     //                // 此处理器将仅应用于HTML模式
     //                TemplateMode.HTML,
     //                // 要应用于名称的匹配前缀
     //                dialectPrefix,
     //                // 标签名称:匹配此名称的特定标签
     //                    null,
     //                // 没有要应用于标签名称的前缀
     //                false,
     //                // 无属性名称:将通过标签名称匹配
     //                    null,
     //                // 没有要应用于属性名称的前缀
     //                    true,
     //                // 优先(内部方言自己的优先)
     //                PRECEDENCE
             	super(TemplateMode.HTML, dialectPrefix, ATTR_NAME, true, null, false, PRECEDENCE);
     
         }
     
         /**
          * 核心处理
          *
          * @param context thymeleaf 上下文对象
          * @param tag   当前节点对象
          * @return
          */
         @Override
         protected void doProcess(ITemplateContext context, IProcessableElementTag tag,
                                  IElementTagStructureHandler structureHandler) {
             // 初始化
             init(context);
             // 获取值
             String dicType = tag.getAttributeValue("dicType");// 字典类型
             String defaultValue = tag.getAttributeValue("defaultValue");// 默认选中
     
             String thValue = IftgUtil.getTargetAttributeValue(context, tag, "th:value");// 回显值
             String defaultSelect = StringUtils.isNoneBlank(thValue) ? thValue : defaultValue;
             List<ValueVO> valueVos = IftgUtil.getValues(dictService, dicType, new String[] { defaultSelect });
             // 创建对象
             createSelect(context, valueVos, structureHandler);
         }
     
     
         /**
          * 初始化
          *
          * @param context
          */
         private void init(ITemplateContext context) {
             if (firstLoad) {
                 ApplicationContext appCtx = SpringContextUtils.getApplicationContext((ITemplateContext) context);
                 dictService = appCtx.getBean(DictService.class);
                 firstLoad = false;
             }
         }
     
         /**
          * 创建select对象
          * @return
          * 		创建将替换自定义标签的DOM结构。 name将显示在“<span>”标签内, 因此必须首先创建, 然后必须向其中添加一个节点。
          *
          */
         private void createSelect(ITemplateContext context, List<ValueVO> options,
                                   IElementTagStructureHandler structureHandler) {
             final IModelFactory modelFactory = context.getModelFactory();
             final IModel model = modelFactory.createModel();
             //添加的element的dom对象并对其添加class的属性
             model.add(modelFactory.createOpenElementTag("select", "class", "form-control chosen-select"));
             model.add(modelFactory.createOpenElementTag("option"));
             model.add(modelFactory.createText("选择类别"));
             model.add(modelFactory.createCloseElementTag("option"));
             // 创建option
             for (ValueVO option : options) {
                 model.add(modelFactory.createOpenElementTag(String.format("option value='%s'", option.getVlaue())));
                 model.add(modelFactory.createText(option.getName()));
                 model.add(modelFactory.createCloseElementTag("option"));
                 IOpenElementTag el = modelFactory.createOpenElementTag("option");
     
             }
             model.add(modelFactory.createCloseElementTag("select"));
             /*
              * 指示引擎用指定的模型替换整个元素。
              */
             structureHandler.replaceWith(model, false);
     
         }
     }
    

自定义标签的工具类

  • IftgUtil
      import com.google.common.collect.Lists;
      import com.sml.dao.sys.Dict;
      import com.sml.service.sys.DictService;
      import com.sml.vo.ValueVO;
      import org.apache.commons.lang3.StringUtils;
      import org.thymeleaf.context.ITemplateContext;
      import org.thymeleaf.model.IProcessableElementTag;
      import org.thymeleaf.standard.expression.IStandardExpression;
      import org.thymeleaf.standard.expression.IStandardExpressionParser;
      import org.thymeleaf.standard.expression.StandardExpressions;
      
      import org.thymeleaf.IEngineConfiguration;
      
      import java.util.*;
      
      /**
       * IftgUtil 辅助工具类
       */
      public class IftgUtil {
      
          private static final String KEY_ALL = "all";
      
          /**
           * 获取数据
           *
           * @param dictService 字典service对象
           * @param dicType     字典类型编码
           * @return
           */
          public static List<ValueVO> getValues(DictService dictService, String dicType) {
              return getValues(dictService, dicType, null);
          }
      
          /**
           * 获取数据
           *
           * @param dictService   字典service对象
           * @param dicType       字典类型编码
           * @param selectedValue 默认选中的值
           * @return
           */
          public static List<ValueVO> getValues(DictService dictService, String dicType, String[] selectedValue) {
              if (StringUtils.isBlank(dicType)) {
                  return Lists.newArrayList();
              }
              if (KEY_ALL.contains(dicType)) {
                  return getListType(dictService, dicType, selectedValue);
              }
      
              Map<String, Object> map = new HashMap<>(16);
              map.put("type", dicType);
              List<Dict> dictDOS = dictService.list(dictService.getSimpleWrapper(map));
              List<ValueVO> options = parseToValues(dictDOS, selectedValue);
              return options;
          }
      
      
      
          public static List<ValueVO> getListType(DictService dictService, String dicType, String[] selectedValue) {
              List<Dict> dictDOS = dictService.listType();
              return parseListTypeToValues(dictDOS, selectedValue);
          }
      
      
          /**
           * 获取标签对应值
           * @param context     thymeleaf 上下文对象
           * @param element       当前节点对象
           * @param attributeName 属性名
           * @return 回显对象值
           */
          public static List<String> getDataValues(ITemplateContext context, IProcessableElementTag element, String attributeName) {
              String attributeValue = element.getAttributeValue(attributeName);
              IEngineConfiguration configuration = context.getConfiguration();
              IStandardExpressionParser expressionParser = StandardExpressions.getExpressionParser(configuration);
              IStandardExpression expression = null;
              try {
                  expression = expressionParser.parseExpression( context, attributeValue);
              } catch (Exception e) {
                  return null;
              }
              List<String> resp = new ArrayList<>();
              Object result = expression.execute( context);
              if (Objects.nonNull(result)
                      && !(result instanceof String)) {
                  resp = (List<String>) (result);
                  return resp;
              } else {
                  if(Objects.nonNull(result)){
                      resp.add(result.toString());
                  }
                  return resp;
              }
      
      
          }
      
      
          /**
           * 获取option 的值
           * @param context     thymeleaf 上下文对象
           * @param element       当前节点对象
           * @param attributeName 属性名
           * @return 标签对象值
           */
          public static String getTargetAttributeValue(ITemplateContext context, IProcessableElementTag element, String attributeName) {
              String attributeValue = element.getAttributeValue(attributeName);
              IEngineConfiguration configuration = context.getConfiguration();
              IStandardExpressionParser expressionParser = StandardExpressions.getExpressionParser(configuration);
              IStandardExpression expression = null;
              try {
                  expression = expressionParser.parseExpression(context, attributeValue);
              } catch (Exception e) {
                  return null;
              }
              Object result = expression.execute(context);
              return result == null ? "" : result.toString();
      
          }
      
          /**
           * 转换格式
           *
           * @param dictDOS 待转换的字典数据
           * @return 转换后的格式
           */
          private static List<ValueVO> parseToValues(List<Dict> dictDOS, String[] selectedValue) {
              List<ValueVO> valueVos = new ArrayList<>();
              ValueVO valueVo = null;
              List<String> selecteds = Objects.nonNull(selectedValue) ? Arrays.asList(selectedValue) : null;
      
              for (Dict dictDO : dictDOS) {
                  valueVo = new ValueVO();
                  valueVo.setName(dictDO.getName());
                  valueVo.setVlaue(dictDO.getValue());
                  if (Objects.nonNull(selecteds) &&
                          selecteds.contains(dictDO.getValue())) {
                      valueVo.setSelected(true);
                  }
                  valueVos.add(valueVo);
              }
              return valueVos;
          }
      
      
      
      
          /**
           * 转换格式(字典大类字典)
           *
           * @param dictDOS 待转换的字典数据
           * @return 转换后的格式
           */
          private static List<ValueVO> parseListTypeToValues(List<Dict> dictDOS, String[] selectedValue) {
              List<ValueVO> valueVos = new ArrayList<>();
              ValueVO valueVo = null;
              List<String> selecteds = Objects.nonNull(selectedValue) ? Arrays.asList(selectedValue) : null;
      
              for (Dict dictDO : dictDOS) {
                  valueVo = new ValueVO();
                  valueVo.setName(dictDO.getDescription());
                  valueVo.setVlaue(dictDO.getType());
                  if (Objects.nonNull(selecteds) &&
                          selecteds.contains(dictDO.getType())) {
                      valueVo.setSelected(true);
                  }
                  valueVos.add(valueVo);
              }
              return valueVos;
          }
      }
    

参考文章

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值