【问题标题】:How to check whether Optional value is null and how to pass it to other method?如何检查 Optional 值是否为 null 以及如何将其传递给其他方法?
【发布时间】:2021-02-09 19:56:54
【问题描述】:

我需要将 dateTs 从 rest 控制器类方法传递到服务类中的 getCars() 方法,该方法将检索在给定时间戳日期注册的汽车,如果时间戳 dateTs(其可选)为空然后它将检索所有汽车。 我认为当前的实现将不起作用,因为如果dateTs 为空,那么它就不能传递给getCars(),它需要Long 类型的值。我应该在哪里以及如何检查dateTs 是否不为空以及如何将相应的值传递给getCars() 并调用适当的方法?

@GetMapping(value = "/get/cars")
public CarList CarController(@Param("dateTs") Optional<Long> dateTs) {
   
return ResponseEntity.ok(carService.getCars((Long) dateSt.get());
} 

服务类方法:

public List<Car> getCars(Long dateSt) {
   List<Car> carList; 
  
   if(dateSt != null){
       carList = carReposistory.retrieveRegisteredCars(dateSt);}
   else{
      carList = carReposistory.retrieveAllCars();} 
       
   return carList;
}

【问题讨论】:

  • null 可以传递给 getCars,因为 Long 是一个对象,你会遇到 long(本机类型)的问题
  • 不确定您所说的“长(本机类型)”是什么意思?我必须使用&lt;Long&gt; dateTs。所以你说没有附加价值的 Long 仍然是一个对象。 dateTs 是一个可选值,所以如果没有提供值,那么我假设没有值的 Long 对象可以进一步处理和传递。如果 dateSt.get() 为 null,会导致任何问题吗?
  • 好吧,我建议您阅读 javadocs,docs.oracle.com/javase/8/docs/api/java/util/Optional.html 获取“如果此 Optional 中存在值,则返回该值,否则抛出 NoSuchElementException。”,所以是的,您将抛出异常正如您在一些答案中看到的那样,您可以使用 orElse(null)

标签: java spring api http optional


【解决方案1】:

请注意:Long 可以是null,因此可以传递给getCars(Long)。它是一个long,不能是null,因为它是一个原语。

问题可能是Optional#get() 抛出一个NoSuchElementException 如果Optional 中没有值(它的值是null),你可以使用Optional#orElse() 像:

return ResponseEntity.ok(carService.getCars((Long) dateSt.orElse(null));

正如其他答案所暗示的那样,使用Optional#isPresent() 是一个(可能更好)的选择。

作为参考,请查看orElsedocumentation


注意 2:还要检查这个问题及其答案:Why should Java 8's Optional not be used in arguments

【讨论】:

    【解决方案2】:

    您可以通过两种方式进行操作。将 Optional 传递给 getCars 或不传递。 通过:

    public List<Car> getCars(Optional<Long> dateSt) {
       if(dateSt.isPresent()){
           return carReposistory.retrieveRegisteredCars(dateSt.get());
       }
       return carReposistory.retrieveAllCars(); 
    }
    

    不通过:你必须创建两个单独的方法:

    public List<Car> retrieveRegisteredCars(Long dateSt) {
       return carReposistory.retrieveRegisteredCars(dateSt);
    }
    
    public List<Car> retrieveAllCars() {
       return carReposistory.retrieveAllCars(); 
    }
    

    并在控制器中使用它们:

    return ResponseEntity.ok(
      dateSt.map(carService::retrieveRegisteredCars)
      .orElseGet(() -> carService.retrieveAllCars())
    );
    

    更新

    或者只是传递null

    return ResponseEntity.ok(carService.getCars((Long) dateSt.orElse(null)));
    

    【讨论】:

      【解决方案3】:

      您通常不想将Optionals 作为参数传递,但我不知道它是否适用于 REST 控制器。见this

      既然说了这么多,你的服务中应该有两种方法,一种用于存在时,一种用于不存在时。

      控制器

      @GetMapping(value = "/get/cars")
      public CarList CarController(@Param("dateTs") Optional<Long> dateTs) {
          return ResponseEntity.ok(
                     dateTs.map(carService::getRegisteredCars)
                           .orElseGet(carService::getAllCars)
                 );
      } 
      

      服务

      public List<Car> getRegisteredCars(Long dateSt) {
          return carReposistory.retrieveRegisteredCars(dateSt);
      }
      
      public List<Car> getAllCars() {
          return carReposistory.retrieveAllCars();
      }
      

      【讨论】:

        猜你喜欢
        • 2012-08-16
        • 2017-03-28
        • 2011-11-29
        • 1970-01-01
        • 1970-01-01
        • 2012-12-26
        • 1970-01-01
        • 2020-05-18
        • 1970-01-01
        相关资源
        最近更新 更多