gpt4 book ai didi

java - 使用 XStream 1.4.2 反序列化 transient 字段

转载 作者:太空宇宙 更新时间:2023-11-04 15:06:27 24 4
gpt4 key购买 nike

我遇到了使用 XStream 1.4.2 反序列化可能是 transient 的字段的要求。尽管如此,此类字段仍可以使用 @XStreamAlias@XStreamAsAttribute 进行注释。是的,我知道,这听起来很奇怪,这是糟糕设计的一个指标,但这就是我目前拥有的。由于 XStream 提供了一种指定自定义转换器的方法,因此我尝试扩展 com.thoughtworks.xstream.converters.reflection.ReflectionConverter 以便覆盖省略所有 transient 字段的默认方法,试图使 XStream 允许反序列化它们。然而,我完全坚持有两个想法来实现这样一个转换器,但它们都不起作用。所以这是我尝试过的:

第一种方法不起作用:

public final class TransientSimpleConverter extends ReflectionConverter {

private final Class<?> type;

private TransientSimpleConverter(Class<?> type, Mapper mapper, ReflectionProvider reflectionProvider) {
super(mapper, reflectionProvider);
this.type = type;
}

public static TransientSimpleConverter transientSimpleConverter(Class<?> type, XStream xStream) {
return new TransientSimpleConverter(type, xStream.getMapper(), xStream.getReflectionProvider());
}

@Override
protected boolean shouldUnmarshalTransientFields() {
return true;
}

@Override
public boolean canConvert(Class type) {
return this.type == type;
}

}

第二种方法也不起作用:

public final class TransientComplexConverter extends ReflectionConverter {

private final Class<?> type;

private TransientComplexConverter(Class<?> type, Mapper mapper, ReflectionProvider provider) {
super(mapper, provider);
this.type = type;
}

public static TransientComplexConverter transientComplexConverter(Class<?> type, Mapper mapper, Iterable<String> fieldNames) {
return new TransientComplexConverter(type, mapper, TransientHackReflectionProvider.transientHackReflectionProvider(type, fieldNames));
}

@Override
public boolean canConvert(Class type) {
return this.type == type;
}

private static final class TransientHackReflectionProvider extends PureJavaReflectionProvider {

private final Class<?> type;
private final Collection<Field> allowedFields;
private final Collection<String> allowedAliases;

private TransientHackReflectionProvider(Class<?> type, Collection<Field> allowedFields, Collection<String> allowedAliases) {
this.type = type;
this.allowedFields = allowedFields;
this.allowedAliases = allowedAliases;
}

public static TransientHackReflectionProvider transientHackReflectionProvider(final Class<?> type, Iterable<String> fieldNames) {
final Collection<Field> allowedFields = from(fieldNames).transform(new Function<String, Field>() {
@Override
public Field apply(String name) {
return field(type, name);
}
}).toList();
final Collection<String> allowedAliases = transform(allowedFields, new Function<Field, String>() {
@Override
public String apply(Field f) {
return f.getName();
}
});
return new TransientHackReflectionProvider(type, allowedFields, allowedAliases);
}

@Override
protected boolean fieldModifiersSupported(Field field) {
return allowedFields.contains(field) ? true : super.fieldModifiersSupported(field);
}

@Override
public boolean fieldDefinedInClass(String fieldName, Class type) {
return type == this.type && allowedAliases.contains(fieldName) ? true : super.fieldDefinedInClass(fieldName, type);
}

private static final Field field(Class<?> type, String name) {
try {
final Field field = type.getDeclaredField(name);
checkArgument(isTransient(field.getModifiers()), name + " is not transient");
checkArgument(field.getAnnotation(XStreamAsAttribute.class) != null, name + " must be annotated with XStreamAsAttribute");
checkArgument(field.getAnnotation(XStreamAlias.class) != null, name + " must be annotated with XStreamAlias");
return field;
} catch (final SecurityException ex) {
throw new RuntimeException(ex);
} catch (final NoSuchFieldException ex) {
throw new RuntimeException(ex);
}
}

}

}

对于解决方法有什么建议或想法吗?提前致谢。

最佳答案

我知道这篇文章已经过时了,但也许有人仍然感兴趣。我的解决方案:

XStream xstream = new XStream(new MyPureJavaReflectionProvider());

class MyPureJavaReflectionProvider extends PureJavaReflectionProvider {

public MyPureJavaReflectionProvider() {
this(new FieldDictionary(new ImmutableFieldKeySorter()));
}

public MyPureJavaReflectionProvider(FieldDictionary fieldDictionary) {
super(fieldDictionary);
}

protected boolean fieldModifiersSupported(Field field) {
int modifiers = field.getModifiers();
return !Modifier.isStatic(modifiers);
}

public boolean fieldDefinedInClass(String fieldName, Class type) {
Field field = fieldDictionary.fieldOrNull(type, fieldName, null);
return field != null && fieldModifiersSupported(field);
}

}

关于java - 使用 XStream 1.4.2 反序列化 transient 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21929024/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com