Заставьте ReflectionToStringBuilder пропустить поля с нулевыми значениями
Я должен напечатать значения объекта в файле журнала. Я использовал:
ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE, true, true);
Но он также печатает нулевые значения, которые я не хочу включать, например:
Pojo @ 117d9a3 [id = 1,name = null, description = Манчестер Юнайтед,KEY=APP-KEY,secretKey=Alex ]
Как подавить нулевые значения от включения?
6 ответов
Более простое решение без подклассов - переопределить метод accept:
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
, так как это private
а также final
поэтому мы не можем продлить это. Реальная вещь происходит в 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);
}
Out of the box implementation exists from Apache commons-lang3:
ReflectionToStringBuilder.toString(new Pojo(), ToStringStyle.DEFAULT_STYLE, true,false, true, null)
Output is as requested:
general.Pojo@3532ec19[description=Manchester,id=1]
Using:
public static String toString(final T object, final ToStringStyle style, final boolean outputTransients,final boolean outputStatics, final boolean excludeNullValues, final Class<? super T> reflectUpToClass)
Ответ @Christian Sporer (поднимите его голос), но он был изменен, чтобы стать утилитарным методом:
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
учебный класс.