How to format string with properties from bean

I want to create a string using the format, replacing some of the formatted markers with the properties from the bean. Is there a library that supports this, or will I have to create my own implementation?

Let me show you 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 specify format strings, for example:

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

and automatically fill the format placeholders with values ​​from the bean, for example:

 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 looked at MessageFormat , but that only allows me to pass numeric indices, not bean.

+7
source share
4 answers

Passed my own, now tested. Comments are 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); } } 
+2
source

Yes, this is possible using the Pojomatic library. Deploy and plug in your own PojoFormatter implementation. Pojomator#doToString(T) can also be interesting.

+1
source

I don’t know how complicated the model you are going to use, but if you want to deal with object trees, I would use my own formatter using Jexl as follows:

  • Initialize Singleex Jexl Engine
  • Fill MapContext with all the objects you want to use when formatting strings
  • Parse your lines and create a Jexl expression for each construction of "$ {}".
  • Evaluate previously created expressions in the context of the object’s context map.

The good thing about Jexl is that it allows you to use method calls, not just properties.

Hope this helps.

0
source

Not quite close, but you can look at StringTemplate, your bean:

 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 } 

Then you can do it like this:

 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" 

Sample code taken from ST4 Introduction

0
source

All Articles