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標籤效果同樣。
相關文章
相關標籤/搜索