Spring WebFlux调用Dataverse API遇空结果的异常处理方案
解决方案
在Spring WebFlux中,Mono不允许映射函数返回null,这是Reactor框架的约束规则,你遇到的"The mapper returned a null value"问题就是因为在map操作里返回null导致的。同时直接访问索引会触发数组越界,需要同时处理这两个问题,正确的做法是当无匹配记录时返回Mono.empty()而非null,具体修改如下:
修改后的代码
@Override public Mono<ClientEntity> findPositionWorkerAssignmentByJobPositionId(UUID jobPositionId) { ODataEntitySetRequest<ClientEntitySet> request = microsoftOData4Client.getRetrieveRequestFactory() .getEntitySetRequest(microsoftOData4Client.newURIBuilder(microsoftOData4Client.getServiceRoot()) .appendEntitySetSegment(positionWorkerAssignmentMapEDMEntitySet.getName()) .expand("cdm_WorkerId", "cdm_JobPositionId") .filter(String.format( "_cdm_jobpositionid_value eq %s and cdm_WorkerId/cdm_workerid ne" + " null" + " and cdm_JobPositionId/cdm_jobpositionid ne null", jobPositionId)) .top(1).build()); request.setPrefer("odata.include-annotations=OData.Community.Display.V1.FormattedValue"); Mono<ODataRetrieveResponse<ClientEntitySet>> blockingRequestWrapper = Mono.fromCallable(request::execute); return blockingRequestWrapper.subscribeOn(Schedulers.boundedElastic()) .flatMap(blockingResponse -> { // 检查响应体和实体列表是否非空 if (blockingResponse.getBody() != null && !blockingResponse.getBody().getEntities().isEmpty()) { return Mono.just(blockingResponse.getBody().getEntities().get(0)); } else { // 无数据时返回空Mono,而非null return Mono.empty(); } }).onErrorStop(); }
关键说明
- 替换
map为flatMap:flatMap支持返回Mono类型,当无匹配记录时返回Mono.empty(),完全符合Reactor的规范,不会触发null相关异常。 - 空值处理逻辑:保留原有的非空检查,确保只有在实体列表存在数据时才访问索引,避免数组越界。
- 后续处理:调用该方法时,可以通过
switchIfEmpty操作符处理空结果,比如返回默认值或抛出业务异常:findPositionWorkerAssignmentByJobPositionId(jobId) .switchIfEmpty(Mono.error(new RuntimeException("未找到匹配的岗位分配记录"))) .subscribe(entity -> { // 处理存在的实体 });
内容的提问来源于stack exchange,提问作者anonymous
相关产品推荐
相关产品推荐

