ModelMapper处理java 8可选<myobjectdto>字段为Optional <myobject> </myobject> </myobjectdto>

时间:2015-02-19 10:23:00

标签: java java-8 optional modelmapper

我一直在应用程序周围使用modelmapper和java 8 Optionals,因为它们是原始类型,所以工作正常;直到我改变了我的一个模型对象&#39;字段到可选类型。然后一切都崩溃了。结果很多库都无法很好地处理泛型。

这是结构

public class MyObjectDto
{
   private Optional<MySubObjectDto> mySubObject;
}

public MyObject
{
   privae Optional<MySubjObject> mySubObject;
}

当我尝试将MyObjectDto映射到MyObject时,modelmapper会调用

public void setMySubObject(Optional<MySubObject> mySubObject){
   this.mySubObject = mySubObject;
}

Optional<MySubObjectDto>,我不明白这是怎么回事(他们之间没有继承)。当然崩溃很快。现在我已经改变了我的二传手接受Dto类型只是为了生存一天,但从长远来看这不会起作用。有没有更好的解决方法,或者我应该创建一个问题?

2 个答案:

答案 0 :(得分:1)

所以我深入研究了模型映射代码并完成了一些通用实现:

modelMapper.createTypeMap(Optional.class, Optional.class).setConverter(new OptionalConverter());

public class OptionalConverter implements ConditionalConverter<Optional, Optional> {

  public MatchResult match(Class<?> sourceType, Class<?> destinationType) {
    if (Optional.class.isAssignableFrom(destinationType)) {
      return MatchResult.FULL;
    } else {
      return MatchResult.NONE;
    }
  }

  private Class<?> getElementType(MappingContext<Optional, Optional> context) {
    Mapping mapping = context.getMapping();
    if (mapping instanceof PropertyMapping) {
      PropertyInfo destInfo = ((PropertyMapping) mapping).getLastDestinationProperty();
      Class<?> elementType = TypeResolver.resolveArgument(destInfo.getGenericType(),
                                                          destInfo.getInitialType());
      return elementType == TypeResolver.Unknown.class ? Object.class : elementType;
    } else if (context.getGenericDestinationType() instanceof ParameterizedType) {
      return Types.rawTypeFor(((ParameterizedType) context.getGenericDestinationType()).getActualTypeArguments()[0]);
    }

    return Object.class;
  }

  public Optional<?> convert(MappingContext<Optional, Optional> context) {
    Class<?> optionalType = getElementType(context);
    Optional source = context.getSource();
    Object dest = null;
    if (source != null && source.isPresent()) {
      MappingContext<?, ?> optionalContext = context.create(source.get(), optionalType);
      dest = context.getMappingEngine().map(optionalContext);
    }

    return Optional.ofNullable(dest);
  }

}

答案 1 :(得分:-1)

对于Optional的用例的一般建议是:返回可空属性。 Optional仅用于业务逻辑代码中,以提高某些典型编码习惯用语的清晰度。您从可以为空的值开始,将其提升为Optional,最后再生成可为空的值(如果适用)。您还可以使用Optional作为处理中某些子例程的返回值。此外,您可以接受它作为此类子例程的参数,但前提是它们是API的内部部分。否则,子程序也会采用可以为空的值,并在内部将其提升为Optional