How do I format a string with properties from a bean

I want to create a String using a format, replacing some tokens in the format with properties from a bean. Is there a library that supports this or am I going to have to create my own implementation?

Let me demonstate with an example. Say I have a bean Person ;

public class Person {
  private String id;
  private String name;
  private String age;

  //getters and setters
}

I want to be able to specify format strings something like;

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

and automatically populate the format placeholders with values from the bean, something like;

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."

I've had a look at MessageFormat but this only seems to allow me to pass numeric indexes, not bean properties.


Rolled my own, testing now. Comments welcome.

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);
  }

}

Yes, it's possible using the Pojomatic library. Implement and plug in your own implementation of PojoFormatter . Pojomator#doToString(T) may be also interesting.


Don't really know how complex is the model you're up to consume but if you want to deal with object trees I would implement my own formatter using Jexl as expession language this way:

  • Initialize a singleton Jexl engine
  • Populate a MapContext with all the objects you want to consume when formatting strings
  • Parse your strings and create a Jexl expression per "${}" construct you have.
  • Evaluate the previous created expressions against the object context map.
  • The good thing about Jexl is that it will allow you to use method calls, not just properties.

    Hope it helps.

    链接地址: http://www.djcxy.com/p/53728.html

    上一篇: Google AdSense和AdBlock

    下一篇: 我如何使用bean的属性格式化字符串