简体   繁体   English

如何使用 commons-lang3 实现 RecursiveToStringStyle 和 JSON_STYLE

[英]How have RecursiveToStringStyle and JSON_STYLE using commons-lang3

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.而且我需要递归地记录类 X 的内容以获取类 Y 并使用 JSON 样式。 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>"}}

I found the solution.我找到了解决方案。 I need to Override the method toString of each classes ( X and Y in this case)我需要Override每个classes toString方法(在本例中为XY

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.现在,使用方法 1 它正在工作。

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.您可以扩展 RecursiveToStringStyle 类来编写自己的样式类并设置参数以匹配 JSON_STYLE 或任何其他样式。

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.要创建自定义样式,最好查看 ToStringStyle 类中设置的样式参数。 You can use the setter methods to customize the default settings in your custom implementation.您可以使用 setter 方法自定义自定义实现中的默认设置。

I had a similar problem and since it was affecting only one field as well, I ended up doing this (I actually use SHORT_PREFIX_STYLE but for the sake of example I keep it as JSON):我有一个类似的问题,因为它也只影响一个字段,所以我最终这样做了(我实际上使用了SHORT_PREFIX_STYLE但为了举例,我将它保留为 JSON):

@Override
public String toString() {
    return (new ReflectionToStringBuilder(this, ToStringStyle.JSON_STYLE) {
        @Override
        protected Object getValue(Field field) throws IllegalArgumentException, IllegalAccessException {
            return "y".equals(field.getName()) ?
                ReflectionToStringBuilder.toString(y, ToStringStyle.JSON_STYLE) :
                super.getValue(field);
        }
    }).toString();
}

Another reason is that I don't have control over field y source code.另一个原因是我无法控制字段y源代码。

(It's too bad that instances of ToStringStyle are not designed in some composable way. I think recursion is not really a part of the "style" at all, it's an aspect of traversion which should have been modeled independently) ToStringStyle实例没有以某种可组合的方式设计,这太糟糕了。我认为递归根本不是“样式”的一部分,它是遍历的一个方面,应该独立建模)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 需要Apache commons-lang3作为使用Tycho构建的Eclipse插件的依赖项 - Need Apache commons-lang3 as dependency of an Eclipse plugin built with Tycho 即使在Struts 2.3.24中添加commons-lang3库之后,也不会出现NoClassDefFoundError - NoClassDefFoundError even after adding commons-lang3 library in Struts 2.3.24 将WAR部署到Wildfly 14时,commons-lang3的ClassNotFoundException - ClassNotFoundException for commons-lang3 when deploying WAR to Wildfly 14 使用 Apache commons-lang3 中的 MethodUtils 调用私有静态方法 - Invoke private static method with MethodUtils from Apache commons-lang3 无法解析org.apache.commons:commons-lang3:3.0对等方未通过身份验证的gradle 2.2.1 - Could not resolve org.apache.commons:commons-lang3:3.0 peer not authenticated gradle 2.2.1 Checker Framework argument.type.incompatible false positive with commons-lang3 - Checker Framework argument.type.incompatible false positive with commons-lang3 在android中使用commons-lang NameValuePair - Using commons-lang NameValuePair in android 结合使用Apache Commons Digester和JSON - Using Apache Commons Digester with JSON 如何使用Play框架下载commons.lang? - How to download commons.lang with Play framework? 如何解决 NoClassDefFoundError: Apache Commons Lang Android - How to solve NoClassDefFoundError: Apache Commons Lang Android
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM