springmvc+freemarker实现自定义标签

1.目标
如图是我们的目标页面的一部分,因为类目列表是每个 页面都需要展示的一部分,所以把这个属性列表提取出来,做成一个自定义标签,在不通的页面上直接引用标签,就可以直接展示了
springmvc+freemarker实现自定义标签_第1张图片
2.编写数据提提供类,实现TemplateDirectiveModel接口

package com.dmall.mall.directive;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.dmall.item.entity.Category;
import com.dmall.item.service.CategoryService;
import com.google.common.base.Strings;

import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateDirectiveModel;
import freemarker.ext.beans.BeansWrapper;
import freemarker.ext.beans.BeansWrapperBuilder;
import freemarker.template.Configuration;
import freemarker.template.SimpleScalar;
/**
* 类目导航组件
*
* @author [email protected]
*
*/
@Component
public class CategoryTreeDirective implements TemplateDirectiveModel{
@Autowired
private CategoryService categoryService;
private Long getPid(Map params)throws TemplateException{
String id = getParam(params, "pid");
if(Strings.isNullOrEmpty(id)){
throw new TemplateModelException("没有指定要展示类目额pid属性");
}
return Long.valueOf(id);
}
@Override
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
throws TemplateException, IOException {
Long pid = getPid(params);
List children = categoryService.findChildren(pid);
env.setVariable("categories", createBeansWrapper().wrap(children));
body.render(env.getOut());
}
protected String getParam(Map params, String name) {
Object value = params.get(name);
if (value instanceof SimpleScalar) {
return ((SimpleScalar)value).getAsString();
}
return null;
}
public BeansWrapper createBeansWrapper() {
return new BeansWrapperBuilder(Configuration.VERSION_2_3_23).build();
}
}
3.将自定义标签的类,放到freemarker配置的变量中
3.在页面中使用自定义标签
这里,我们把每个自定义标签对应的ftl独立成 一个单独的文件,这样,就可以在多个页面中去include了,如图
springmvc+freemarker实现自定义标签_第2张图片

category_tree.ftl文件的内容:
<@categoryTree pid="1">
<#list categories as category>
<#if category.hasChild==1>
${category.name}
<@categoryTree pid="${category.id}">
<#list categories as c>
<#else>
其中@categoryTree是我们在上个步骤中 在freemarker 配置中 定义的key, 这样freemarker在解析的时候就会使用与key对应的组件处理类来执行,自定义组件也支持传递参数,在这个例子中,我们要展示的一个树形菜单,所以我们要把上级菜单ID传递进去(pid),组件处理类处理完后,通过 env.setVariable("categories", createBeansWrapper().wrap(children));把结果放到模版渲染上下文中,这样在@categoryTree标签内就可以使用组件提供的处理结果了

你可能感兴趣的:(Java)