我如何遍历[[tokens]]列表并用文本框输入替换它们?

时间:2010-01-19 10:00:25

标签: java templates oop hashmap

以下是我正在尝试的基本代码:

Field fields[] = SalesLetter.class.getDeclaredFields();
String fieldName;

for (int j = 0, m = fields.length; j < m; j++) {
       fieldName = fields[j].getName(); //example fieldname [[headline]]
       templateHTML = templateHTML.replace(fieldName, Letter.fieldName());
}

我相信我通过尝试getDeclaredFields(在语法上甚至不正确)来解决它。当我完成我的标题时,它提出了一些其他stackoverflow问题,我在写这篇文章之前已经阅读过。他们是:

Best way to replace tokens in a large text template Replacing tokens in a string from an array

它给了我从文本文件中读取所有合法[[tokens]]的想法,将它们放入哈希(错误我的意思是地图,这是java:D),然后创建一个具有相同名称的对象引用那个令牌。

我无法弄清楚如何在java中专门做这样的事情,或者如果这样做的话。请协助。

提前致谢,

科迪古德曼

注意:我正在努力使所有内容尽可能灵活,所以也许在将来我可以添加诸如“[[tokenname]]之类的东西:这是令牌名称,你需要真正考虑客户想要什么在文本文件中提出一个好的令牌名称,然后在我的表单上生成这些字段,一切正常:)

2 个答案:

答案 0 :(得分:1)

为了从类型的非静态字段读取值,您需要引用该类型的实例:

public class ReflectFields {
  static class Letter {
    public int baz = 100;
  }

  static class SalesLetter extends Letter {
    public String foo = "bar";
  }

  public static void main(String[] args) throws Exception {
    // TODO: better exception handling, etc.
    SalesLetter instance = new SalesLetter();
    for (Field field : instance.getClass().getFields()) {
      System.out.format("%s = %s%n", field.getName(), field.get(instance));
    }
  }
}

你还必须注意私人领域等。一般来说,应该避免这种方法,因为它通过查看类内部来打破封装。

考虑使用JavaBean API。

public class BeanHelper {
  private final Object bean;
  private final Map<String, Method> getters = new TreeMap<String, Method>();

  public BeanHelper(Object bean) {
    this.bean = bean;
    for (PropertyDescriptor pd : Introspector.getBeanInfo(bean.getClass(),
          Object.class).getPropertyDescriptors()) {
      getters.put(pd.getName(), pd.getReadMethod());
    }
  }

  public Set<String> getProperties() { return getters.keySet(); }

  public Object get(String propertyName) {
    return getters.get(propertyName).invoke(bean);
  }

  public static void main(String[] args) {
    BeanHelper helper = new BeanHelper(new MyBean());
    for (String prop : helper.getProperties()) {
      System.out.format("%s = %s%n", prop, helper.get(prop));
    }
  }

  public static class MyBean {
    private final String foo = "bar";
    private final boolean baz = true;
    public String getFoo() { return foo; }
    public boolean isBaz() { return baz; }
  }
}

为简洁起见,省略了异常处理,因此您需要添加一些try / catch块(我建议在IllegalStateException s中包装已捕获的异常)。

答案 1 :(得分:0)

如何使用FreemarkerVelocityStringTemplate等模板引擎:

  • [[替换为${,将]]替换为}
  • 从包含替换项的属性文件创建模型
  • 处理templateHTML

这里有一个Freemarker示例(没有异常处理)

Configuration config = new Configuration();
StringTemplateLoader loader = new StringTemplateLoader();
config.setTeplateLoader(loader);

Map model = Properites.load(new FileInputStream("tokens.properties"));
loader.putTemplate("html.ftl", templateHTML);
Template template = config.getTemplate("html.ftl");

Writer out = new StringWriter();
template.process(root, out);
String result = out.toString();

StringTemplate可能更简单(由[[替换]]$),但我与它并不相似:

Map model = Properites.load(new FileInputStream("tokens.properties"));
StringTemplate template = new StringTemplate(templateHTML);
template.setAttributes(model);
String result = template.toString();

tokens.properties文件如下所示:

tokenname:this is token name