How have RecursiveToStringStyle and JSON_STYLE using commons-lang3

10,222

Solution 1

I found the solution. I need to Override the method toString of each classes (X and Y in this case)

public Class X {

  private String a;
  private String b;
  private Y y;

  @Override
  public String toString() {
    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
  }
}

public Class Y {
  private String c;
  private String d;

  @Override
  public String toString() {
    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
  }
}

And now, with the approach 1 It's working.

Solution 2

You can extend the RecursiveToStringStyle class to write your own style class and set the parameters to match the JSON_STYLE or any other style for that matter.

class CustomStyle extends RecursiveToStringStyle {

    public CustomStyle() {
        super();
        super.setUseClassName(false);
        super.setUseIdentityHashCode(false);
        super.setContentStart("{");
        super.setContentEnd("}");
        super.setArrayStart("[");
        super.setArrayEnd("]");
        super.setFieldSeparator(",");
        super.setFieldNameValueSeparator(":");
        super.setNullText("null");
        super.setSummaryObjectStartText("\"<");
        super.setSummaryObjectEndText(">\"");
        super.setSizeStartText("\"<size=");
        super.setSizeEndText(">\"");
    }
}

public class Z {
    public String objectToString(Object obj) {
        ToStringStyle style = new CustomStyle();
        return new ReflectionToStringBuilder(obj, style).toString();
    }
}

To create a custom style, a good point will be to look at the style parameters set in the ToStringStyle class. You can use the setter methods to customize the default settings in your custom implementation.

Share:
10,222

Related videos on Youtube

Leonel
Author by

Leonel

Updated on June 04, 2022

Comments

  • Leonel
    Leonel almost 2 years

    I'm using the dependency:

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
    

    I have the following objects:

    public Class X {
    
      private String a;
      private String b;
      private Y y;
    }
    
    public Class Y {
      private String c;
      private String d;
    }
    

    And I need to log the content of the class X recursively to get the class Y as well and using the JSON style. That is my goal and this is the purpose of this question.

    Approach 1:

    ToStringStyle style = ToStringStyle.JSON_STYLE;
    LOGGER.debug(ReflectionToStringBuilder.toString(new X(), style, false, false));
    

    Approach 1 result:

    {"a":"<a>","b":"<b>","y": com.<packages>.y@<hash>}
    

    Approach 2:

    RecursiveToStringStyle style = new RecursiveToStringStyle();
    LOGGER.debug(ReflectionToStringBuilder.toString(new X(), style, false, false));
    

    Approach 2 result:

    [com.<packages>.x@<hash>[a=<a>,b=<b>,y=com.<packages>.y@<hash>[c=<c>,d=<d>]]
    

    Successful Approach:

    `Merge of Approach 1 and Approach 2` but how to achieve this? 
    

    Successful Approach result (My goal):

    {"a":"<a>","b":"<b>","y":{"c":"<c>","d":"<d>"}}
    
  • hansvb
    hansvb over 8 years
    Sure, that would work, if you can change the toString methods of all involved classes. The nice thing about the ToStringBuilder is that it can be external. But why make things more complicated than necessary.
  • Kristian Holdhus
    Kristian Holdhus over 5 years
    Note: This approach will output values that feel like JSON, but which do not parse as JSON. In particular, it does not quote field names or string values. This is because String-quoting is implemented as part of the JsonToStringStyle class, in method called appendValueAsString().