本地南通网站建设,做公众号的网站有哪些,拿品牌做网站算侵权吗,如何打开谷歌网站相信大家在使用 thymeleaf 的时候#xff0c;绝大部分都是和 springboot 一块儿使用的#xff0c;所以 th:field 属性用的很舒服。
但实际上#xff0c;th:field 只有在 spring 环境下下有用#xff0c;单独的 thymeleaf 是不支持的#xff01;
为什么我知道呢#xff…相信大家在使用 thymeleaf 的时候绝大部分都是和 springboot 一块儿使用的所以 th:field 属性用的很舒服。
但实际上th:field 只有在 spring 环境下下有用单独的 thymeleaf 是不支持的
为什么我知道呢因为在把若依的底层 spring 剔除替换为 loveqq 的时候发现表单用的 th:field 的数据没有回显
而网上都是 spring 环境下的没办法只能看看源码了。具体过程就不详细写了这里直接贴一下如何实现 th:field。
其实很简单只要自定义 AbstractAttributeTagProcessor 就可以了代码如下 首先是基础实现类 AbstractLoveqqAttributeTagProcessor
package com.kfyty.loveqq.framework.boot.template.thymeleaf.autoconfig.processor;import com.kfyty.loveqq.framework.core.utils.BeanUtil;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.engine.AttributeDefinition;
import org.thymeleaf.engine.AttributeDefinitions;
import org.thymeleaf.engine.AttributeName;
import org.thymeleaf.engine.IAttributeDefinitionsAware;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.AbstractAttributeTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.util.Validate;import java.util.HashMap;
import java.util.Map;/*** 描述: 标签处理器** author kfyty725* date 2024/6/05 18:55* email kfyty725hotmail.com*/
public abstract class AbstractLoveqqAttributeTagProcessor extends AbstractAttributeTagProcessor implements IAttributeDefinitionsAware {protected static final String ID_ATTR_NAME id;protected static final String TYPE_ATTR_NAME type;protected static final String NAME_ATTR_NAME name;protected static final String VALUE_ATTR_NAME value;protected static final String CHECKED_ATTR_NAME checked;protected static final String SELECTED_ATTR_NAME selected;protected static final String DISABLED_ATTR_NAME disabled;protected static final String MULTIPLE_ATTR_NAME multiple;protected AttributeDefinition idAttributeDefinition;protected AttributeDefinition typeAttributeDefinition;protected AttributeDefinition nameAttributeDefinition;protected AttributeDefinition valueAttributeDefinition;protected AttributeDefinition checkedAttributeDefinition;protected AttributeDefinition selectedAttributeDefinition;protected AttributeDefinition disabledAttributeDefinition;protected AttributeDefinition multipleAttributeDefinition;public AbstractLoveqqAttributeTagProcessor(final String dialectPrefix, final String elementName, final String attributeName, final int precedence) {super(TemplateMode.HTML, dialectPrefix, elementName, false, attributeName, true, precedence, false);}Overridepublic void setAttributeDefinitions(AttributeDefinitions attributeDefinitions) {Validate.notNull(attributeDefinitions, Attribute Definitions cannot be null);this.idAttributeDefinition attributeDefinitions.forName(TemplateMode.HTML, ID_ATTR_NAME);this.typeAttributeDefinition attributeDefinitions.forName(TemplateMode.HTML, TYPE_ATTR_NAME);this.nameAttributeDefinition attributeDefinitions.forName(TemplateMode.HTML, NAME_ATTR_NAME);this.valueAttributeDefinition attributeDefinitions.forName(TemplateMode.HTML, VALUE_ATTR_NAME);this.checkedAttributeDefinition attributeDefinitions.forName(TemplateMode.HTML, CHECKED_ATTR_NAME);this.selectedAttributeDefinition attributeDefinitions.forName(TemplateMode.HTML, SELECTED_ATTR_NAME);this.disabledAttributeDefinition attributeDefinitions.forName(TemplateMode.HTML, DISABLED_ATTR_NAME);this.multipleAttributeDefinition attributeDefinitions.forName(TemplateMode.HTML, MULTIPLE_ATTR_NAME);}Overrideprotected void doProcess(ITemplateContext context, IProcessableElementTag tag, AttributeName attributeName, String attributeValue, IElementTagStructureHandler structureHandler) {if (this.continueProcess(context, tag, attributeName, attributeValue, structureHandler)) {this.doProcessInternal(context, tag, attributeName, attributeValue, structureHandler);}}protected boolean continueProcess(ITemplateContext context, IProcessableElementTag tag, AttributeName attributeName, String attributeValue, IElementTagStructureHandler structureHandler) {return this.getMatchingAttributeName().getMatchingAttributeName().getAttributeName().equals(attributeName.getAttributeName());}protected abstract void doProcessInternal(ITemplateContext context, IProcessableElementTag tag, AttributeName attributeName, String attributeValue, IElementTagStructureHandler structureHandler);public static Object buildEvaluatorContext(ITemplateContext context) {MapString, Object params new HashMap();Object target context.getSelectionTarget();// 先将目标属性放进去if (target ! null) {params BeanUtil.copyProperties(target);}// 搜索变量放进去for (String variableName : context.getVariableNames()) {Object variable context.getVariable(variableName);params.put(variableName, variable);}return params;}
}然后是 th:field 的实现
package com.kfyty.loveqq.framework.boot.template.thymeleaf.autoconfig.processor;import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component;
import com.kfyty.loveqq.framework.core.utils.OgnlUtil;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.engine.AttributeName;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.standard.util.StandardProcessorUtils;import java.util.Map;
import java.util.Objects;/*** 描述: input field 处理器** author kfyty725* date 2024/6/05 18:55* email kfyty725hotmail.com*/
Component
public class LoveqqInputFieldTagProcessor extends AbstractLoveqqAttributeTagProcessor {public LoveqqInputFieldTagProcessor() {this(th);}public LoveqqInputFieldTagProcessor(String dialectPrefix) {super(dialectPrefix, input, field, 0);}Overrideprotected void doProcessInternal(ITemplateContext context, IProcessableElementTag tag, AttributeName attributeName, String attributeValue, IElementTagStructureHandler structureHandler) {MapString, String attributeMap tag.getAttributeMap();String field attributeValue.replaceAll([*{}], );String value OgnlUtil.compute(field, buildEvaluatorContext(context), String.class);if (!attributeMap.containsKey(NAME_ATTR_NAME)) {StandardProcessorUtils.setAttribute(structureHandler, this.nameAttributeDefinition, NAME_ATTR_NAME, field);}if (value ! null !attributeMap.containsKey(VALUE_ATTR_NAME)) {StandardProcessorUtils.setAttribute(structureHandler, this.valueAttributeDefinition, VALUE_ATTR_NAME, value);}if (value ! null Objects.equals(tag.getAttribute(TYPE_ATTR_NAME).getValue(), radio)) {LoveqqInputCheckboxTagProcessor.processRadio(value, this.checkedAttributeDefinition, context, tag, structureHandler);}}
}还有 th:checked 实现
package com.kfyty.loveqq.framework.boot.template.thymeleaf.autoconfig.processor;import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component;
import com.kfyty.loveqq.framework.core.utils.OgnlUtil;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.engine.AttributeDefinition;
import org.thymeleaf.engine.AttributeName;
import org.thymeleaf.exceptions.TemplateProcessingException;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.standard.util.StandardProcessorUtils;import java.util.Map;
import java.util.Objects;/*** 描述: input checkbox 处理器** author kfyty725* date 2024/6/05 18:55* email kfyty725hotmail.com*/
Component
public class LoveqqInputCheckboxTagProcessor extends AbstractLoveqqAttributeTagProcessor {public LoveqqInputCheckboxTagProcessor() {this(th);}public LoveqqInputCheckboxTagProcessor(String dialectPrefix) {super(dialectPrefix, input, checked, 0);}Overrideprotected void doProcessInternal(ITemplateContext context, IProcessableElementTag tag, AttributeName attributeName, String attributeValue, IElementTagStructureHandler structureHandler) {MapString, String attributeMap tag.getAttributeMap();String express attributeValue.replaceAll([*${}], );String value OgnlUtil.compute(express, buildEvaluatorContext(context), String.class);// radio checked 处理if (value ! null Objects.equals(tag.getAttribute(TYPE_ATTR_NAME).getValue(), radio)) {processRadio(value, this.checkedAttributeDefinition, context, tag, structureHandler);}// 其他 checked 处理else {if (value ! null !attributeMap.containsKey(CHECKED_ATTR_NAME)) {StandardProcessorUtils.setAttribute(structureHandler, this.checkedAttributeDefinition, CHECKED_ATTR_NAME, value);}}}public static void processRadio(String value, AttributeDefinition checkedAttributeDefinition, ITemplateContext context, IProcessableElementTag tag, IElementTagStructureHandler structureHandler) {String checkedValue;if (tag.getAttribute(value) ! null) {checkedValue tag.getAttributeValue(value);} else if (tag.getAttribute(th:value) ! null) {String express tag.getAttributeValue(th:value).replaceAll([*${}], );checkedValue OgnlUtil.compute(express, buildEvaluatorContext(context), String.class);} else {throw new TemplateProcessingException(The input radio tag not found value.);}if (Objects.equals(checkedValue, value)) {StandardProcessorUtils.setAttribute(structureHandler, checkedAttributeDefinition, CHECKED_ATTR_NAME, value);}}
}最后需要把他们放入方言实现中
package com.kfyty.loveqq.framework.boot.template.thymeleaf.autoconfig.dialect;import lombok.RequiredArgsConstructor;
import org.thymeleaf.processor.IProcessor;
import org.thymeleaf.standard.StandardDialect;import java.util.Set;/*** 描述: loveqq 方言实现** author kfyty725* date 2024/6/05 18:55* email kfyty725hotmail.com*/
RequiredArgsConstructor
public class LoveqqStandardDialect extends StandardDialect {private final SetIProcessor processors;Overridepublic SetIProcessor getProcessors(String dialectPrefix) {SetIProcessor processorSet super.getProcessors(dialectPrefix);if (this.processors ! null) {processorSet.addAll(this.processors);}return processorSet;}
}使用 LoveqqStandardDialect 方言实现并创建的时候将上面的两个处理器放进来就可以了。