gpt4 book ai didi

java - Orika:从字符串映射到 SomeObjects 列表

转载 作者:行者123 更新时间:2023-11-30 02:41:04 26 4
gpt4 key购买 nike

考虑以下情况:

public class A {
private String stringA;

public String getStringA() {
return stringA;
}

public void setStringA(String stringA) {
this.stringA = stringA;
}

}

public class B {

List<SomeObject> someObjects;

public List<SomeObject> getSomeObjects() {
if (someObjects == null) {
someObjects = new ArrayList<SomeObject>();
}
return someObjects;
}

}

public class SomeObject {
private String stringSomeObject;

public String getStringSomeObject() {
return stringSomeObject;
}

public void setStringSomeObject(String stringSomeObject) {
this.stringSomeObject = stringSomeObject;
}

}

我想从 A 映射至B 。在映射这些的同时,stringA需要映射到stringSomeObjectSomeObject 。我尝试为此编写一个 Orika-Mapper:

public class MyMapper extends ConfigurableMapper {

@Override
protected void configure(MapperFactory factory) {
ConverterFactory converterFactory = factory.getConverterFactory();
converterFactory.registerConverter(new StringToSomeObjectConverter());

factory.classMap(A.class, B.class) //
.field("stringA", "someObjects") //
.byDefault() //
.register();
}

}

它映射类 AB每当遇到 String 的转换时至List<SomeObject>它调用自定义转换器:

public class StringToSomeObjectConverter extends CustomConverter<String, List<SomeObject>> {

private static final String BORROWER_PARTY_TYP_CODE = "147";

@Override
public List<SomeObject> convert(String source, Type<? extends List<SomeObject>> destinationType) {
SomeObject someObject = new SomeObject();
someObject.setStringSomeObject(source);
return Arrays.asList(someObject);
}

}

我编写了一个单元测试来确保其有效:

@Test
public void testMap() throws Exception {
A a = new A();
a.setStringA("a");

B outcome = new MyMapper().map(a, B.class);

assertThat(outcome.getSomeObjects.size(), is(1));
}

遗憾的是这个测试失败了:

java.lang.AssertionError: 
Expected: is <1>
but: was <0>

似乎转换器从未执行过,所以我尝试调试它。事实上:调试器永远不会到达转换器。难道我做错了什么?这好像是。我知道还有更多方法可以使用,例如:mapAToB 例如...

好吧,我找到了解决方案...不!这不是一个解决方案,它只是一个解决方法。我定义了 stringAList<String>并定义了一个扩展 CustomConverter<String, LoanContrReqERPCrteReqLoanContrBrrwrPty> 的转换器。

因为这感觉有点“hacky”,所以我仍然对一个好的解决方案感兴趣。 (虽然我只是认为这个解决方案可能没问题:现在两个对象的数据结构比以前更平等。问题是,该对象 B 来自外部服务,我无法修改它。)

最佳答案

您的映射不起作用,因为您没有 someObjects 的 setter 。

当 Orika 尝试为映射器生成代码时,它会检查 classMap 中的所有 fieldMapsourceProperty 是否可读且 destinationProperty code> 是可分配的。如果检查通过,生成器会将字段转换放入生成的映射器中。如果检查失败,Orika 会跳过此字段转换。

可以用来解决问题的几个选项:

  • 您可以为 B 类中的 someObjects 字段添加 setter:

    public static class B {

    List<SomeObject> someObjects;

    public List<SomeObject> getSomeObjects() {
    if (someObjects == null) {
    someObjects = new ArrayList<SomeObject>();
    }
    return someObjects;
    }

    public void setSomeObjects(List<SomeObject> someObjects) {
    this.someObjects = someObjects;
    }
    }
  • 使用自定义映射器而不是转换器:

        factory.classMap(A.class, B.class)
    .customize(
    new CustomMapper<A, B>() {
    @Override
    public void mapAtoB(A a, B b, MappingContext context) {
    SomeObject someObject = new SomeObject();
    someObject.setStringSomeObject(a.getStringA());
    b.getSomeObjects().add(someObject);
    }
    }
    )
    .byDefault()
    .register();

Orika 将在解析字段映射后调用 customMapper。
生成的映射器将如下所示:

    b.setOtherField(a.getOtherField());
if (customMapper != null) {
customMapper.map(source, destination); <-- Your mapper invocation
}
  • 对字段使用以下语法:

        factory.classMap(A.class, B.class)
    .field("stringA", "someObjects[0].stringSomeObject")
    .byDefault()
    .register();

生成的映射器将如下所示:

    if (source.getStringA() != null) {
if (((((java.util.List) destination.getSomeObjects()).size() <= 0 || ((List) destination.getSomeObjects()).get(0) == null))) {
((java.util.List) destination.getSomeObjects()).add(0, ((BoundMapperFacade) usedMapperFacades[0]).newObject(((String) source.getStringA()), mappingContext));
}
}

if (!(((java.lang.String) source.getStringA()) == null)) {
(((java.util.List) destination.getSomeObjects()).get(0)).setStringSomeObject(source.getStringA());
} else if (!(((java.util.List) destination.getSomeObjects()) == null) && !((((java.util.List) destination.getSomeObjects()).size() <= 0 || ((List) destination.getSomeObjects()).get(0) == null))) {
( ((java.util.List) destination.getSomeObjects()).get(0)).setStringSomeObject(null);
}

Orika 中还存在一个错误,即使用语法 .field("stringA", "elements{stringB}") ( Incorrect mapper code generated for mapping from a single property to property of collection element ) 从单个属性映射到集合属性。 Bug 已于 2016 年 12 月 31 日关闭:Fix for bug

关于java - Orika:从字符串映射到 SomeObjects 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41674023/

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