How to log internals of an arbitrary object in Java?
I have a Java object with some unknown structure. Now I want to output this structure (properties and their values) to log file. And of course I'm interested to do this in rec开发者_StackOverflow中文版ursive mode. Are there any libraries that can help me?
XStream is extremely good at printing object graphs, even handling cycles without any extra configuration or extra code in your classes (i.e. no messing with toString()'s). Just add the library and you can do this to anything and get nice, useful output:
log.debug("The object: {}", new XStream().toXML(anyObject));
That will give you XML output. If you prefer JSON, you can get it with a tiny bit more work as detailed in the XStream JSON tutorial.
I suggest you look either at Apache Commons BeanUtils or Apache Commons Lang, specifically ReflectionToStringBuilder.
Java serialization, which comes with Java, should do the trick. It will be in binary format though.
There is also XML serialization which can be provided by JAXB
you could use reflection
getClass and then go over each instance variable and go on (some objects can be handled specifically (like Strings))
You should use reflection. Have a look at java.lang.Class
class, specifically .getFields()
method.
I have found the Apache Commons ToStringBuilder.reflectionToString()
very useful. To get recursion you can override each Object's toString() method with a call to this function passing this
.
http://commons.apache.org/lang/api-2.6/org/apache/commons/lang/builder/ToStringBuilder.html
The java reflection API will give you access to all of this stuff (private members and all). To get private members, you will need to get yourObject.getClass().getDeclaredFields()
to access a private field, remember to call yourField.setAccesible(true)
on it.
Of course, you are very quickly going to run into problems by handrolling your own class to do this via reflection. The main problems come in when trying to decide to finally print a value and determining if it is an enum, a primitive, a primitive array and so on. You can use the Class.isPrimitive method to help figure that step out. To access elements of an array, use the java.lang.reflect.Array class.
The best option, which was posted earlier, is to use the ReflectionToStringBuilder of apache commons.
A json serializer will do the job, e.g. using Gson:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
...
private static final Logger LOG = LoggerFactory.getLogger(Your.class);
...
Object obj = ...;
LOG.info(new Gson().toJson(obj));
精彩评论