如何减少 Optionals 抛出一次错误

How to reduce Optionals to throw an error once

我有以下响应来自 rest 调用并根据返回的内容执行一些逻辑。

这就是我想要的。

如果整体状态代码不是 200 或者 如果在 SimpleResponse 列表中,SimpleResponse 对象的 none 有 200 个 httpCode,抛出错误。

下面的例子不完整。

  1. 太多了,在另一个可选中有一个可选。
  2. 然后在 2 个不同的地方抛出相同的错误。
  3. 此外,如果可选结果为空,请说 responseEntity.getBody(),也想抛出同样的错误。

有没有更简洁的写法?

这些是 2 个相关对象

@Getter
@Setter
public class SimpleResponses {
    private List<SimpleResponse> simpleResponsesList;
}

@Getter
@Setter
public class SimpleResponse {
    private String httpCode;
    // ... other fields
}

方法调用 rest 调用并在需要时抛出错误。

public ResponseEntity<SimpleResponses> get() {

    HttpEntity<Object> httpEntity = this.getEntity();
    // restTemplate is from Spring
    ResponseEntity<SimpleResponses> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, SimpleResponses.class);


// START
// This is the logic to throw error depending on output as mentioned above.
// looking for a better way to write this. 

    // if none of the object inside the list has 200 code, throw error
    Optional.ofNullable(responseEntity.getBody())
            .map(SimpleResponses::getSimpleResponses)
            .ifPresent(response -> {
                Optional<SimpleResponse> simpleResponse = response.stream()
                        .filter(responseStream -> responseStream.getHttpCode().equals("200"))
                        .findAny();
                if (!simpleResponse.isPresent()) {
                    throw new CustomRuntimeException("Failed ..... "); // repetitive same error being thrown again below.
                }
            });

    // if overall code is not 200, throw error too 
    if (!responseEntity.getStatusCode().is2xxSuccessful()) {
        throw new CustomRuntimeException("Failed ..... ");
    }

// END


    return responseEntity;
}

使用Optional::flatMapOptional::ifPresentOrElse可以提供以下解决方案:

Optional.ofNullable(responseEntity.getBody())
    .flatMap(body -> SimpleResponses.getSimpleResponses(body) // SimpleResponses
        .getSimpleResponsesList()
        .stream() // Stream<SimpleResponse>
        .filter(sr -> "200".equals(sr.getHtppCode()))
        .findAny() // Optional<SimpleResponse>
    )
    .ifPresentOrElse( // Java 9
        System.out::println, 
        () -> { throw new CustomRuntimeException("Bad response"); }
    );

对于Java8,可以使用Optional::orElseThrow

SimpleResponse good = Optional.ofNullable(responseEntity.getBody())
    .flatMap(body -> SimpleResponses.getSimpleResponses(body) // SimpleResponses
        .getSimpleResponsesList()
        .stream() // Stream<SimpleResponse>
        .filter(sr -> "200".equals(sr.getHtppCode()))
        .findAny() // Optional<SimpleResponse>
    )
    .orElseThrow(() -> new CustomRuntimeException("Bad response"));

System.out.println(good);