使ReflectionToStringBuilder跳过无效值



我必须在日志文件中打印对象值。我用过:

ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE, true, true);

,但它也打印了我不想包括的空值,例如:

pojo@117d9a3 [id = 1, name = null ,description = Manchester United,key = app-key,secretkey,secretkey = alex]

如何抑制被包括在内的空值?

一个没有子类别的简单解决方案是覆盖接受方法:

public String toStringWithAttributes() {
    Object myself = this;
    ReflectionToStringBuilder builder = new ReflectionToStringBuilder(
            this, ToStringStyle.SHORT_PREFIX_STYLE) {
            @Override
            protected boolean accept(Field field) {
                try {
                    return super.accept(field) && field.get(myself) != null;
                } catch (IllegalAccessException e) {
                    return super.accept(field);
                }
            }
    };
    return builder.toString();
}

这具有额外的好处,您可以使用所需的任何ToStringStyle,而格式化是完美的。

您必须提供自己的ToStringStyle实现。这样的东西(未经测试!):

import org.apache.commons.lang.SystemUtils;
import org.apache.commons.lang.builder.ToStringStyle;
public final class NotNullToStringStyle extends ToStringStyle {
    public static final ToStringStyle NOT_NULL_STYLE = new NotNullToStringStyle();
    private static final long serialVersionUID = 1L;
    /**
     * <p>Constructor.</p>
     *
     * <p>Use the static constant rather than instantiating.</p>
     */
    NotNullToStringStyle() {
        super();
        this.setContentStart("[");
        this.setFieldSeparator(SystemUtils.LINE_SEPARATOR + "  ");
        this.setFieldSeparatorAtStart(true);
        this.setContentEnd(SystemUtils.LINE_SEPARATOR + "]");
    }
    /**
     * <p>Ensure <code>Singleton</code> after serialization.</p>
     *
     * @return the singleton
     */
    private Object readResolve() {
        return NOT_NULL_STYLE;
    }
    @Override
    public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {
        if (value != null) {
            appendFieldStart(buffer, fieldName);
            appendInternal(buffer, fieldName, value, isFullDetail(fullDetail));
            appendFieldEnd(buffer, fieldName);
        }
    }
}

大多数代码都是从MultiLineToStringStyle复制的,因为它是privatefinal,因此我们无法将其扩展。真实的事情发生在append方法中。这是最初的参考:

    public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {
        appendFieldStart(buffer, fieldName);
        if (value == null) {
            appendNullText(buffer, fieldName);
        } else {
            appendInternal(buffer, fieldName, value, isFullDetail(fullDetail));
        }
        appendFieldEnd(buffer, fieldName);
    }

从apache commons-lang3:

中存在框实现。

reflectionToStringBuilder.ToString(new Pojo(),tostringstyle.default_style,true,true,false, true ,null)

输出按要求:

general.Pojo@3532ec19[description=Manchester,id=1]

使用:
公共静态字符串tostring(最终T对象,最终的Tostringstyle样式,最终的布尔输出传输,最终的布尔量输出史塔式,最终布尔值排除,最终类;超级t&gt;Reflectoplass)

@christian sporer的答案(抬起他),但被修改为可重复使用的util方法:

public class ToStringUtil {
  public static String toStringWithAttributes(Object ofInterest, ToStringStyle style) { 
    ReflectionToStringBuilder builder = new ReflectionToStringBuilder(ofInterest, style) { 
      @Override
      protected boolean accept(Field field) {
        try { return super.accept(field) && field.get(ofInterest) != null; }
        catch (IllegalAccessException e) { return super.accept(field); }
      }
    };
    return builder.toString();
  }
}

自3.6起,有一个内置的方法

ReflectionToStringBuilder.toString(this, ToStringStyle.DEFAULT_STYLE,false,false,true,null);

方法签名是:

ReflectionToStringBuilder.toString(
   Object object, 
   ToStringStyle style, 
   boolean outputTransients, 
   boolean outputStatics, 
   boolean excludeNullValues, 
   Class<? super Object> reflectUpToClass)

有一种方法可以用自己的文本在此对象上创建新的toStringStyle对象setNullText(String nullText),然后将此ToStringStyle对象传递到ReflectionToStringBuilder类的构造函数中。

相关内容

  • 没有找到相关文章

最新更新