struts2+freemarker中使用标签

在ftl页面中使用struts2的标签是支持的,但不是完全支持。
在ftl页面中可以使用的的所有的struts2标签都定义在org.apache.struts2.views.freemarker.tags.StrutsModels中。
正常情况下我们可以<@s.tag></@s.tag>使用标签
这里大家可能要问这个s是怎么来的呢?
这个s大家可以在struts-default.xml中找到
<bean type="org.apache.struts2.views.TagLibrary" name="s" class="org.apache.struts2.views.DefaultTagLibrary" />
然后在org.apache.struts2.views.freemarker.FreemarkerManager中对其进行了包装,原理和其他的Request……一样(注意这里面有两个地方,在容器启动时候s表示的类是DefaultTagLibrary)。而访问具体的action的时候s代表具体的是StrutsModels,FreemarkerManager里关于“s”的处理有两个地方,看一下FreemarkerManager就知道了。

其次我发现在ftl中不能使用debug标签,原因很简单struts不支持,因为StrutsModels没有定义这个标签。
但是我们可以自己实现类此的这种功能。

附带源码如下:
package myfreemarker;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.struts2.StrutsException;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.reflection.ReflectionProvider;

import freemarker.core.Environment;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

public class DebugDirective implements TemplateDirectiveModel
{

protected ReflectionProvider reflectionProvider;

@Inject
public void setReflectionProvider(ReflectionProvider prov)
{
this.reflectionProvider = prov;
}

@Override
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body)
throws TemplateException, IOException
{
if (!params.isEmpty())
{
throw new TemplateModelException("This debug directive doesn't allow parameters.");
}
if (loopVars.length != 0)
{
throw new TemplateModelException("This debug directive doesn't allow loop variables.");
}
if (body == null)
{
Configuration cfg = env.getConfiguration();
Template template = cfg.getTemplate("debug.ftl");

ActionContext context = ActionContext.getContext();
ValueStack stack = context.getValueStack();

context.getContainer().inject(cfg.getSharedVariable("debug"));
Iterator iter = stack.getRoot().iterator();
List stackValues = new ArrayList(stack.getRoot().size());

while (iter.hasNext())
{
Object o = iter.next();
Map values;
try
{
values = reflectionProvider.getBeanMap(o);
}
catch (Exception e)
{
throw new StrutsException("Caught an exception while getting the property values of " + o, e);
}
stackValues.add(new DebugMapEntry(o.getClass().getName(), values));
}

Map parameters = new LinkedHashMap();
parameters.put("stackValues", stackValues);

Map root = new HashMap();
root.put("stack", stack);
root.put("parameters", parameters);

Writer writer = env.getOut();
template.process(root, writer);
}
else
{
throw new RuntimeException("debug directive do not need body");
}

}

private static class DebugMapEntry implements Map.Entry
{
private Object key;

private Object value;

DebugMapEntry(Object key, Object value)
{
this.key = key;
this.value = value;
}

public Object getKey()
{
return key;
}

public Object getValue()
{
return value;
}

public Object setValue(Object newVal)
{
Object oldVal = value;
value = newVal;
return oldVal;
}
}
}





然后用设置全局变量的方式 ,把这个directive “注册”一下,页面就可以使用了,和struts的debug标签效果一样。

你可能感兴趣的:(struts2+freemarker中使用标签)