如何使用bean的属性格式化字符串



我想使用一种格式创建一个String,用bean的属性替换格式中的一些令牌。是否有一个库支持这个功能,或者我必须创建自己的实现?

让我用一个例子来说明。假设我有一个bean Person;

public class Person {
  private String id;
  private String name;
  private String age;
  //getters and setters
}

我希望能够指定格式字符串,比如;

"{name} is {age} years old."
"Person id {id} is called {name}."

并自动用bean中的值填充格式占位符,例如;

String format = "{name} is {age} old."
Person p = new Person(1, "Fred", "32 years");
String formatted = doFormat(format, person); //returns "Fred is 32 years old."

我已经看了一下MessageFormat,但这似乎只允许我传递数字索引,而不是bean属性。

自己滚动,现在正在测试。欢迎评论。

import java.lang.reflect.Field;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class BeanFormatter<E> {
  private Matcher matcher;
  private static final Pattern pattern = Pattern.compile("\{(.+?)\}");
  public BeanFormatter(String formatString) {
    this.matcher = pattern.matcher(formatString);
  }
  public String format(E bean) throws Exception {
    StringBuffer buffer = new StringBuffer();
    try {
      matcher.reset();
      while (matcher.find()) {
        String token = matcher.group(1);
        String value = getProperty(bean, token);
        matcher.appendReplacement(buffer, value);
      }
      matcher.appendTail(buffer);
    } catch (Exception ex) {
      throw new Exception("Error formatting bean " + bean.getClass() + " with format " + matcher.pattern().toString(), ex);
    }
    return buffer.toString();
  }
  private String getProperty(E bean, String token) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
    Field field = bean.getClass().getDeclaredField(token);
    field.setAccessible(true);
    return String.valueOf(field.get(bean));
  }
  public static void main(String[] args) throws Exception {
    String format = "{name} is {age} old.";
    Person p = new Person("Fred", "32 years", 1);
    BeanFormatter<Person> bf = new BeanFormatter<Person>(format);
    String s = bf.format(p);
    System.out.println(s);
  }
}

是的,可以使用Pojomatic库。实现并插入您自己的PojoFormatter实现。Pojomator#doToString(T)可能也很有趣

我不知道你要使用的模型有多复杂但如果你想处理对象树,我会使用Jexl作为表达式语言实现我自己的格式化器,如下所示:

  1. 初始化单例Jexl引擎
  2. 在格式化字符串时,用你想要使用的所有对象填充MapContext
  3. 解析你的字符串和创建一个Jexl表达式每"${}"构造你有。
  4. 根据对象上下文映射计算前面创建的表达式。

Jexl的好处是它允许你使用方法调用,而不仅仅是属性。

希望能有所帮助。

不太接近,但是您可以查看您的bean StringTemplate:

public static class User {
    public int id; // template can directly access via u.id
    private String name; // template can't access this
    public User(int id, String name) { this.id = id; this.name = name; }
    public boolean isManager() { return true; } // u.manager
    public boolean hasParkingSpot() { return true; } // u.parkingSpot
    public String getName() { return name; } // u.name
    public String toString() { return id+":"+name; } // u
}

然后你可以这样渲染:

ST st = new ST("<b>$u.id$</b>: $u.name$", '$', '$');
st.add("u", new User(999, "parrt"));
String result = st.render(); // "<b>999</b>: parrt"

上面的代码示例取自ST4 Introduction

最新更新