返回通用类型

时间:2019-07-17 18:48:09

标签: java spring clean-architecture vavr

我正在编写Spring应用程序,我想将其分为几层,以将域与框架完全分开。

因此,我的域方法返回了vavr的Either<Error, T>,而我的控制器对所有这些方法都使用了简单的解析器。

  <T> ResponseEntity resolve(Either<Error, T> either) {
        return either
           .map(this::successResponse)
           .getOrElseGet(this::failureResponse);
  }

  private ResponseEntity<Object> successResponse(Object obj) {
        return new ResponseEntity<>(mapper.toDto(obj), HttpStatus.OK);
  }

问题是,我不想从控制器返回域实体,所以我编写了通用映射器,该映射器将使用单个方法将每个域对象转换为其dto。

 public <T, Y> Y toDto(T domainObject) {        
     if(domainObject instanceof Reservation) {
         return (Y) reservationMapper.toDto((Reservation)domainObject);
     }
     return null;
 }

ReservationReservationMapper在这里是一个域的具体实现,if当然可以用更好的解决方案代替,但事实并非如此。

情况是,它不起作用。扔

  

java.lang.ClassCastException:类   com.johndoe.reservationsystem.adapter.dto.ReservationDto不能为   强制转换为org.springframework.util.MultiValueMap类

我发现一种解决方法是创建空的抽象类Dto,使我所有的dto类都对此进行扩展,然后仅在Dto方法中返回Y而不是toDto。关键是,我不太喜欢它,我想找到更好的解决方案。

可能没有必要,但这是ReservationMapper

的实现
class ReservationMapper {
    ReservationDto toDto(Reservation reservation) {
        return ReservationDto.builder()
                .id(reservation.getId())
                .ownerId(reservation.getOwnerId())
                .reservedObjectId(reservation.getReservedObjectId())
                .title(reservation.getTitle())
                .description(reservation.getDescription())
                .startDate(reservation.getStartDate())
                .endDate(reservation.getEndDate())
                .build();
    }
}

1 个答案:

答案 0 :(得分:0)

您的方法签名

public <T, Y> Y toDto(T domainObject)

是造成问题的原因,因为在您调用的上下文中

return new ResponseEntity<>(mapper.toDto(obj), HttpStatus.OK)

被解释为能够返回MultiValueMap<String, String>以符合构造函数

public ResponseEntity(MultiValueMap<String, String> headers, HttpStatus status)

请参阅javadoc:ResponseEntity(MultiValueMap<String, String>, HttpStatus)

通过修改您的toDto方法,使其明确表示肯定不会返回MultiValueMap,您可以解决此问题。例如,只需指定:

public Object toDto(Object domainObject)
转换方法的

可能会做到。或者,您可以约束您的通用参数,以便明确表明它无法基于其调用当前所在的类型推断上下文返回任意类型的实例。