Dealing with Java Beans via Apache Bean Utils

Posted by & filed under , , .

Ok some of you are probably already familiar with the Apache CommonsBeanUtils framework, so this might not come as a surprise, but I have just discovered recently a class which I found myself in the past implementing bits of, one way or another: the BeanMap class! I swear, when dealing with loading random properties from properties files and trying to map those onto bean properties — going through the whole Reflection API, this can turn into a nightmare. Having worked with the Commons Collections in the past, I spotted the BeanMap class there first (yup, that’s where it started!) and then noticed it’s been deprecated and will be removed. Luckily, Apache Commons team is doing that because this has been (rightly so!) moved now into BeanUtils.

So with that in mind, here’s a nicer way of dealing with setting bean properties on-the-fly.

I mentioned before reading properties from a file and assigning those values to bean properties — this might not be the best example (though I had in the past had to implement support for properties files which change during app runtime), so imagine for example a different scenario: where you “consume” a service (let’s say REST-like) which depending on parameters passed in, can return different “types”. You have your REST parsing library, this however is a generic one which returns you just some implementation of Map with key/value pairs. Now you have to match these against a few bean classes — let the fun start!

Of course you can do something like this:

if( "I passed this parameters" ) {
 //we know it's class A
 for( String key : map.keySet() ) {
  if( "propertyOne".equals(key))
   bean.setPropertyOne( map.get(key) );
 } else ...
}

but your code will look messy! AND you have to address it every time you change/add/remove a property!

This is where BeanMap comes in handy: you can simply wrap your bean in a BeanMap then use this construct:

beanMap.putAll( map );

One single line!

I’ve put together a quick-and-dirty example though which hopefully will exemplify a few of (what I consider to be) the best parts of BeanMap: consider a simple bean class JacksMagicBean with just 2 properties — magicWord and magicNumber. Now, to set the bean properties you’d use setMagicWord(...) or to retrieve them you’d use getMagicWord(), right? But with BeanMap you can change all that to … get("magicWord"), or put("magicWord", value)! You don’t even need to know the bean properties upfront — can store this in a properties/xml/text file, or even have them passed to you when you receive your response in the above example! And the good side is that you can pick and choose in between which way you’re going to get/set these properties since you will always be able to retrieve the wrapped bean — via getBean() — so you get the best of both worlds!

I’m not including in this blog post entry the full class code (though the source code is attached fully at the end of this post for download), only looking at the “testing” methods I’ve put together to exemplify this:

/* TESTING */
/**
 * Shows how to retrieve all the <b>read-only</b> properties of the bean.
 */
public void retrieveFields() {
 System.out.println("--- retrieveFields");
 BeanMap bm = new BeanMap(new JacksMagicBean());
 for (Object o : bm.keySet())
  System.out.println(o);
}
 
/**
 * Shows how values can be assigned more easily.
 */
public void manipulateFields() {
 JacksMagicBean bean = new JacksMagicBean(42, "please");
 BeanMap bm = new BeanMap(bean);
 
 System.out.println("--- magicNumber");
 Object number = bm.get("magicNumber");
 System.out.println(number.getClass() + " : " + number.toString());
 bm.put("magicNumber", 21);
 System.out.println(bean.getMagicNumber());
 bm.put("magicNumber", "71");
 System.out.println(bean.getMagicNumber());
 
 System.out.println("--- magicWord");
 Object word = bm.get("magicWord");
 System.out.println(word.getClass() + " : " + word.toString());
 bm.put("magicWord", "sesame");
 System.out.println(bean.getMagicWord());
 bm.put("magicWord", new StringBuilder("abc"));
 System.out.println(bean.getMagicWord());
}

Now as you can see in the above code, you can mix and match the way of dealing with these properties. Even better, you have a very nice and quick way of accessing all the bean properties — without dealing with the whole Reflection API! (That in itself, as a side note, I found as a big plus, as I don’t like the Reflection API at best of times — too clunky when all you want is to find out the list of properties and interrogate a couple of properties.)

Also, the other good thing, as you can see above, is that you can assign String values to numeric properties — and they get parsed and set automatically (the case with the magicNumber property above). So getting back to the properties file mentioned above — you can definitely use this in a scenario like this since the Properties class only deals with String’s!

As promised, below, the full source code: JacksMagicBean.java

Leave a Reply

Your email address will not be published.