freemarker+jstl自定义标签实现动态表单的显示

上一篇文章中,已经对freemarker做了简单的了解;动态表单的概念大家也应该不陌生了,在《浅析动态表单》文章中已经做了一定的分析;jstl自定义标签也比较熟悉了,在此之前已经使用多次了。今天我们就使用freemarker+jstl自定义标签实现动态表单的显示。

下面是我总结的使用动态表单的主要步骤,大家做个参考:


1、定义Map对象

本例在SSH项目里面实现,所以需要配置ActionForm,Document为本例的应用,其对应的ActionForm中另外添加类型为Map的props属性,用来获得与设置模板的变量:

public class DocumentActionForm extends ActionForm {
	private int id;
	/**
	 * 页面上通过:
	 * <input type="text" name="props(KEY)" >
	 * 			------->getProps().put(KEY,value)
	 */
	private Map props = new HashMap();
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public Map getProps() {
		return props;
	}
	public void setProps(Map props) {
		this.props = props;
	}
}



2、定义模板

我们将模板都定义成.ftl文件,便于嵌套使用。下面列出了本例子当中的一些模板:


document_form.ftl:该模板定义表单域内容,也就是说,本例子主要通过该模板进行动态显示。根据用户相应的操作,该模板会根据fieldInput中的template属性,调用不同的子模板。

<table class="tableEdit" style="width:580px;" cellspacing="0" border="0" cellpadding="0">
<#assign i = 0>
<#list form.fields as field>
	<#assign i = i + 1>
	<#if field_index % 2 = 0>
	<tr>
	</#if>
                <!--fieldLabel为actionForm里面定义的标签字段,此处意思为从表单域中取出标签-->
		<td class="tdEditLabel" >${field.fieldLabel}</td>			
                <!--fieldInput里面的template字段表示模板的名称,针对这个页面表单元素,如何呈现为HTML代码-->
		<td class="tdEditContent"><#include "${field.fieldInput.template}"></td>
	<#if i = 2 || !field_has_next>
	<#assign i = 0>
	</tr>
	</#if>
</#list>
</table>


下面分别是file.ftl、select.ftl和text.ftl对应的子模板:

<input type="file" name="props(${field.fieldName})">


<select name="props(${field.fieldName})">
	<#list field.items as item>
	<option value="${item.value}">${item.label}</option>
	</#list>
</select>


<input type="text" name="props(${field.fieldName})">


3、读取模板的方法:

FreeMarkerManager类里面定义了加载模板、设置对象包装器、设置异常处理器等一系列模板处理的步骤,也就是包含了对对模板的处理。

public class FreeMarkerManager {
	private static Configuration cfg =new Configuration();
	static{
		//定义模板的位置:从类路径中,相对于FreeMarkerManager所在的路径加载模板
		cfg.setTemplateLoader(new ClassTemplateLoader(FreeMarkerManager.class, "templates"));
		//设置对象包装器
		cfg.setObjectWrapper(new DefaultObjectWrapper());
		//设置异常处理器
		cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
	}
	public static Configuration getConfiguration(){
		return cfg;
	}
}


4、JSTL自定义函数的实现

本方法里面得到模板配置对象,对模板进行解释,进行输出。

/**
 * 用于freemarker的jstl界面显示函数
 * @author lzq
 *
 */
public class DynaFormFunction {
	private static FormManager formManager;
	private static String defaultTemplate="document_form.ftl"; 
	public static String form(int workflowId){
		try {
			//查找表单定义
			FlowForm form = formManager.findForm(workflowId);
			if (form == null) {
				return null;
			}
			//得到模板配置
			Configuration cfg =FreeMarkerManager.getConfiguration();
			Template template = null;
			if (form.getTemplate() == null || form.getTemplate().trim().equals("")) {
				template = cfg.getTemplate(defaultTemplate);
			}else {
				template = cfg.getTemplate(form.getTemplate());
			}
			//最终输出的位置
			Writer out = new StringWriter();
			//数据模型
			Map rootMap = new HashMap();
			rootMap.put("form", form);
			//模板引擎,解释模板
			template.process(rootMap, out);
			return out.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	public void setFormManager(FormManager formManager) {
		DynaFormFunction.formManager = formManager;
	}
	public void setDefaultTemplate(String defaultTemplate) {
		DynaFormFunction.defaultTemplate = defaultTemplate;
	}
}


JSTL自定义标签的对应的配置my.tld文件:

<?xml version="1.0" encoding="UTF-8" ?>
<taglib>
  <tlib-version>1.1</tlib-version>
  <short-name>my</short-name>
  <uri>http://www.lzq.com/functions</uri>
  <function>
    <name>form</name>
    <function-class>com.lzq.web.DynaFormFunction</function-class>
    <function-signature>java.lang.String form(int)</function-signature>
  </function>
</taglib>


页面调用JSTL:

${my:form(documentForm.workflowId) }


如此,便能在页面上显示动态的表单了。

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 30
    评论
在 Spring Boot 中使用 Freemarker 自定义标签,可以通过以下步骤实现: 1. 创建一个自定义标签类,继承 `freemarker.template.TemplateDirectiveModel` 接口,并实现其中的 `execute` 方法,该方法用于处理自定义标签的逻辑。 ```java @Component public class CustomTagDirective implements TemplateDirectiveModel { @Autowired private UserService userService; // 举例注入一个服务类 @Override public void execute(Environment environment, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException { // 处理自定义标签逻辑,可以使用 environment、params、body 等参数 String userId = params.get("userId").toString(); User user = userService.getUserById(userId); environment.getOut().write(user.getName()); } } ``` 2. 在 Spring Boot 的配置文件中注册自定义标签类。 ```java @Configuration public class FreemarkerConfig { @Autowired private CustomTagDirective customTagDirective; @Bean public FreeMarkerConfigurer freeMarkerConfigurer() { FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setTemplateLoaderPath("classpath:/templates"); Map<String, Object> variables = new HashMap<>(); variables.put("customTag", customTagDirective); configurer.setFreemarkerVariables(variables); return configurer; } } ``` 3. 在 Freemarker 模板中使用自定义标签。 ```html <#assign userId = "1" /> <@customTag userId=userId /> ``` 在以上代码中,我们首先通过 `<#assign>` 定义了一个变量 `userId`,然后通过 `<@customTag>` 调用自定义标签,并将 `userId` 作为参数传入。 这样就可以在 Spring Boot 中使用自定义Freemarker 标签了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值