是否可以在注释中使用 NamedMapConverter?如何?
Is it possible to use NamedMapConverter in annotation? How?
我想使用 NamedMapConverter 的某个变体(来自 XStream 库)。
new NamedMapConverter(xstream.getMapper(), "mapping", "value", String.class, "color", HexColor.class, true, true, xstream.getConverterLookup());
但我想将其用作注释。我的猜测在下面。 HexColor 的 SingleValueConverter 已经实现。
@XStreamConverter(value = NamedMapConverter.class, strings = { "mapping", "value", "color" }, booleans = { true, true }, types = { String.class, HexColor.class })
private Map<String, HexColor> colorMappings;
但是,令人惊讶的是,它不起作用。我究竟做错了什么?示例结果如下。
<colorMappings>
<mapping>
<value>Something</value>
<color>007cc2</color>
</mapping>
</colorMappings>
我找到了奇怪行为的原因。这是由 XStream 库中的错误引起的。 AnnotationMapperclass中有一个cacheConverter方法
private Converter cacheConverter(final XStreamConverter annotation,
final Class targetType) {
Converter result = null;
final Object[] args;
final List<Object> parameter = new ArrayList<Object>();
if (targetType != null && annotation.useImplicitType()) {
parameter.add(targetType);
}
final List<Object> arrays = new ArrayList<Object>();
arrays.add(annotation.booleans());
arrays.add(annotation.bytes());
arrays.add(annotation.chars());
arrays.add(annotation.doubles());
arrays.add(annotation.floats());
arrays.add(annotation.ints());
arrays.add(annotation.longs());
arrays.add(annotation.shorts());
arrays.add(annotation.strings());
arrays.add(annotation.types());
for(Object array : arrays) {
if (array != null) {
int length = Array.getLength(array);
for (int i = 0; i < length; i++ ) {
Object object = Array.get(array, i);
if (!parameter.contains(object)) {
parameter.add(object);
}
}
}
}
下面重复了关键片段。
if (!parameter.contains(object)) {
parameter.add(object);
}
因此,如果任何数组中有两个相似的值(在本例中为布尔值 true 和 true,但其他重复值也会出现此问题),则只会将其中一个添加到参数中.因此,参数列表将是错误的(缺少一个布尔值)并且与正确的构造函数不匹配。
但是,目前我不知道如何围绕该问题进行编码。
一个简单(但丑陋)的修复方法是创建扩展 NamedMapConverter 的新转换器
public class BetterNamedMapConverter extends NamedMapConverter {
public BetterNamedMapConverter(Mapper mapper, String entryName, String keyName, Class keyType, String valueName, Class valueType,
boolean asAttributes, ConverterLookup lookup) {
super(mapper, entryName, keyName, keyType, valueName, valueType, asAttributes, asAttributes, lookup);
}
}
并将注释更改为
@XStreamConverter(value = BetterNamedMapConverter.class, strings = { "mapping", "value", "color" }, booleans = { true }, types = { String.class, HexColor.class }, useImplicitType = false)
仍然,这个错误让我感到困惑(在某些情况下,解决它需要更糟糕的黑客攻击)。
我想使用 NamedMapConverter 的某个变体(来自 XStream 库)。
new NamedMapConverter(xstream.getMapper(), "mapping", "value", String.class, "color", HexColor.class, true, true, xstream.getConverterLookup());
但我想将其用作注释。我的猜测在下面。 HexColor 的 SingleValueConverter 已经实现。
@XStreamConverter(value = NamedMapConverter.class, strings = { "mapping", "value", "color" }, booleans = { true, true }, types = { String.class, HexColor.class })
private Map<String, HexColor> colorMappings;
但是,令人惊讶的是,它不起作用。我究竟做错了什么?示例结果如下。
<colorMappings>
<mapping>
<value>Something</value>
<color>007cc2</color>
</mapping>
</colorMappings>
我找到了奇怪行为的原因。这是由 XStream 库中的错误引起的。 AnnotationMapperclass中有一个cacheConverter方法
private Converter cacheConverter(final XStreamConverter annotation,
final Class targetType) {
Converter result = null;
final Object[] args;
final List<Object> parameter = new ArrayList<Object>();
if (targetType != null && annotation.useImplicitType()) {
parameter.add(targetType);
}
final List<Object> arrays = new ArrayList<Object>();
arrays.add(annotation.booleans());
arrays.add(annotation.bytes());
arrays.add(annotation.chars());
arrays.add(annotation.doubles());
arrays.add(annotation.floats());
arrays.add(annotation.ints());
arrays.add(annotation.longs());
arrays.add(annotation.shorts());
arrays.add(annotation.strings());
arrays.add(annotation.types());
for(Object array : arrays) {
if (array != null) {
int length = Array.getLength(array);
for (int i = 0; i < length; i++ ) {
Object object = Array.get(array, i);
if (!parameter.contains(object)) {
parameter.add(object);
}
}
}
}
下面重复了关键片段。
if (!parameter.contains(object)) {
parameter.add(object);
}
因此,如果任何数组中有两个相似的值(在本例中为布尔值 true 和 true,但其他重复值也会出现此问题),则只会将其中一个添加到参数中.因此,参数列表将是错误的(缺少一个布尔值)并且与正确的构造函数不匹配。
但是,目前我不知道如何围绕该问题进行编码。
一个简单(但丑陋)的修复方法是创建扩展 NamedMapConverter 的新转换器
public class BetterNamedMapConverter extends NamedMapConverter {
public BetterNamedMapConverter(Mapper mapper, String entryName, String keyName, Class keyType, String valueName, Class valueType,
boolean asAttributes, ConverterLookup lookup) {
super(mapper, entryName, keyName, keyType, valueName, valueType, asAttributes, asAttributes, lookup);
}
}
并将注释更改为
@XStreamConverter(value = BetterNamedMapConverter.class, strings = { "mapping", "value", "color" }, booleans = { true }, types = { String.class, HexColor.class }, useImplicitType = false)
仍然,这个错误让我感到困惑(在某些情况下,解决它需要更糟糕的黑客攻击)。