为了账号安全,请及时绑定邮箱和手机立即绑定

Optional 返回值为 null 时不抛异常

Optional 返回值为 null 时不抛异常

开满天机 2023-04-13 10:40:30
我正在学习 Spring Boot,当服务在数据库中找不到项目时,我试图抛出异常,因此,我尝试使用可选的,但是当我测试它时,除了异常之外,我只得到一个空响应    @GetMapping(value = "/compras", produces = "application/json")public Optional<Compras> retrieveAllCompras(@RequestParam String id) {    return Optional.of(compraRepository.findById(id)).orElseThrow(RuntimeException::new);当在数据库中找不到该项目时,我希望出现异常
查看完整描述

4 回答

?
婷婷同学_

TA贡献1844条经验 获得超8个赞

Optional.of期望纯值。您也可以在文档中找到信息,


/**

 * Constructs an instance with the described value.

 *

 * @param value the non-{@code null} value to describe

 * @throws NullPointerException if value is {@code null}

 */

private Optional(T value) {

    this.value = Objects.requireNonNull(value);

}

例子,


jshell> Optional.of(100)

$2 ==> Optional[100]


jshell> Optional.of(null)

|  Exception java.lang.NullPointerException

|        at Objects.requireNonNull (Objects.java:221)

|        at Optional.<init> (Optional.java:107)

|        at Optional.of (Optional.java:120)

|        at (#1:1)

如果您的价值可能null在运行时,您可以使用.ofNullable,


jshell> Optional.ofNullable(null)

$3 ==> Optional.empty

ALSO 函数式编程的思想是为所有输入返回一个值,而不是抛出Exception破坏函数组合的值。


jshell> Function<Integer, Optional<Integer>> f = x -> Optional.of(x + 1)

f ==> $Lambda$23/0x0000000801171c40@6996db8


jshell> Function<Integer, Optional<Integer>> g = x -> Optional.of(x * 2)

g ==> $Lambda$24/0x0000000801172840@7fbe847c


jshell> f.apply(5).flatMap(x -> g.apply(x))

$13 ==> Optional[12]

因此,在您的示例中,您可以将Optional.empty()其视为未找到的项目,但 Spring 也会考虑这一点,200这仍然比 throw 更好500。您可能希望发送404准确。


@GetMapping(

  value = "/compras", 

  produces = "application/json"

)

public Optional<Compras> retrieveAllCompras(@RequestParam String id) {

    return Optional.ofNullable(compraRepository.findById(id)); //will response as 200 even when no item found

}

您可以用来ResponseEntity<A>设置特定的 http 状态

传统的响应方式404是定义特定的异常。


import org.springframework.web.server.ResponseStatusException;

import org.springframework.http.HttpStatus;


@GetMapping(

  value = "/compras", 

  produces = "application/json"

)

public Compras retrieveAllCompras(@RequestParam String id) {

    return Optional.ofNullable(compraRepository.findById(id))

                   .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "item not found"))

}


查看完整回答
反对 回复 2023-04-13
?
慕妹3242003

TA贡献1824条经验 获得超6个赞

想想这里的类型,如果你要返回Optional,你会做一个.orElse,你必须重新包装它。这将是一种方法:


 @GetMapping(value = "/compras", produces = "application/json")

public Optional<Compras> retrieveAllCompras(@RequestParam String id) {

    return Optional.ofNullable(compraRepository.findById(id)).

                     map(Optional::of).

                     orElseThrow(() -> new RuntimeException("Not found"));

我会解释:

  1. Optional.ofNullable()将返回一个Optional<Compras>, 具有值Optional("some compras")或值Optional.Empty

  2. map(Optional::of)将再次包装可选的,所以你将拥有Optional[Optional<Compras>]或(这里的技巧)Optional.Empty,因为地图不包装 Optional.Empty(这是他加入我们的原因)

  3. 最后,orElseThrow(() -> new RuntimeException("Not found"))将解压你的可选,在这种情况下从Optional[Optional<Compras>]Optional<Compras>或者,如果是Optional.Empty它将抛出异常


查看完整回答
反对 回复 2023-04-13
?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

你的控制器返回Optional<Compras>。这意味着不会#get调用方法。如果值,您的控制器将返回 null Optional

更改为:public Compras retrieveAllCompras...你会得到你的例外


查看完整回答
反对 回复 2023-04-13
?
青春有我

TA贡献1784条经验 获得超8个赞

从对象名称和调用的方法 ( compraRepository.findById(id)) 来看,您的服务实际上是一个存储库。如果它是 Spring Data 存储库,那么您应该将创建留给OptionalSpring Data: Null Handling of Repository Methods。所以你会有

compraRepository.findById(id).orElseThrow(NotFoundException::new)


查看完整回答
反对 回复 2023-04-13
  • 4 回答
  • 0 关注
  • 150 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信