【问题标题】:Reactive Spring Query Parameters反应式 Spring 查询参数
【发布时间】:2018-03-01 06:16:01
【问题描述】:

我的 Spring Reactive Web API 应该能够根据查询参数进行过滤,但我很难做到这一点。

GET /v1/address?type=business

应该返回系统中所有类型为“business”的地址(只是一个例子,因为我没有发布实际需求)。如果参数不存在,则返回所有地址。

[
  { "id" : 1, "type" : "business", "street" : "..."},
  { "id" : 2, "type" : "business", "street" : "..."},
  ...
}

我正在使用路由器功能来映射请求:

public RouterFunction<ServerResponse> route(AddressHandler handler) {
    return route(GET("/v1/address"), handler::getAddresses);
}

但我正在努力确定如何检查参数,如果不存在,则返回所有地址。

class AddressHandler {
    Mono<ServerResponse> getAddressesFilteredOrNot(ServerRequest request) {
        Optional<String> addressType = request.getQueryParam("type");

        ...
    }
}

现在 Optional.ifPresent() 不起作用,我无法从该方法返回:

class AddressHandler {
    Mono<ServerResponse> getAddressesFilteredOrNot(ServerRequest request) {
        Optional<String> addressType = request.getQueryParam("type");

        // invalid
        addressType.ifPresent(addrType -> {
            return ServerResponse.ok()
                .body(this.service.getAddressByType(addrType),
                   Address.class);
    });
}

我也不能在参数上 switchIfEmpty(),因为它会抛出 NullPointerException:

class AddressHandler {
    Mono<ServerResponse> getAddressesFilteredOrNot(ServerRequest request) {
        Optional<String> addressType = request.getQueryParam("type");

        // also invalid
        return Mono.justOrEmpty(addressType.orElse(""))
               .flatMap(addrType -> ServerResponse.ok().body(this.service.getAddressByType(addrType), Address.class)
               .switchIfEmpty(ServerResponse.ok().body(this.service.getAllAddresses(), Address.class));
    });
}

如果查询参数存在并且依赖 getAllAddresses() 方法,使用查询参数的流程是什么?真的可以吗?

【问题讨论】:

    标签: spring-boot reactive handlers queryparam


    【解决方案1】:

    您可以使用OptionalorElse()orElseGet() 功能来调用替代方法。例如:

    request
        .getQueryParam("type")
        .map(type -> service.getAddressByType(type))
        .orElseGet(() -> service.getAllAddresses());
    

    在这种情况下,orElseGet() 更有意义,因为它是延迟调用的。请注意,尽管这两种方法应该具有相同的返回类型,所以可能是Flux&lt;Address&gt;

    【讨论】:

    • 感谢 g00glen00b,我觉得我从错误的角度来处理这个问题。理想情况下,请求参数需要成为这种方法的一等公民,而不是有一个调用的方法: service.findAll() 。我应该将过滤器参数传递给服务,例如 Flux
      findAll(filterParams) {}。自从您在 Optional 上回答了问题后,我将接受这一点,但我会以更好的方法来解决此问题。 :)
    • 不,我能够将您的答案放到上下文中,这很有意义 - 我只是用一些错误处理来修饰它。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-15
    • 2017-12-16
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 2021-10-29
    相关资源
    最近更新 更多