0

这是我的代码中的以下流程:用户调用创建代理端点,包含代理名称和布尔字段->

路由器函数接收调用,传递给处理程序->

处理程序将请求正文转换为单声道,将该单声道传递给服务->

Service 将代理保存到 DB,在此过程中生成一个 ID,然后创建一个 Response 对象,其中包含包装在 Mono 中的 ID,将 Response 返回给 Handler。

这是我卡住的部分。保持反应式方法,我必须将代理保存到 Db 并在 Mono 的“doOnNext() 部分中创建 ID。但是,我无法返回从 DB 获取的 ID 以创建响应对象。

实现此目的的反应方式是什么?提前致谢!

public RouterFunction<ServerResponse> createAgency() {
        return RouterFunctions
                .route(POST("/agency").and(accept(MediaType.APPLICATION_JSON)), handler::createAgency);
    }
@Component
@AllArgsConstructor
public class AgencyHandler {

    private final AgencyServiceImpl service;

    @NonNull
    public Mono<ServerResponse> createAgency(ServerRequest request){
        Mono<CreateAgencyRequest> agency = request.bodyToMono(CreateAgencyRequest.class);

        Mono<CreateAgencyResponse> response = service.createAgency(agency);

        return ServerResponse.created(URI.create("/agency"))
                .contentType(MediaType.APPLICATION_JSON)
                .body(response, CreateAgencyResponse.class);
    }
}
@Service
@AllArgsConstructor
public class AgencyServiceImpl implements AgencyService {
    private final AgencyRepository agencyRepository;
    private final UuidGenerator uuidGenerator;

    public Mono<CreateAgencyResponse> createAgency(Mono<CreateAgencyRequest> request) {
        UUID id;
        request.doOnNext(agency -> {
            UUID agencyId = uuidGenerator.getUUID();
            Mono<Agency> newAgency = Mono.just(
                new Agency(
                    agencyId,
                    agency.getFields().getName()
            ));

            //repository.save(newAgency)

            //return Mono.just(new CreateAgencyResponse(new CreateAgencyResponseData(agencyId.toString())));
        });

        // return request
        return Mono.just(new CreateAgencyResponse(new CreateAgencyResponseData(agencyId.toString())));
    }
}
4

3 回答 3

1

像下面这样的东西应该可以解决问题:

@Service
@AllArgsConstructor
public class AgencyServiceImpl implements AgencyService {
    private final AgencyRepository agencyRepository;
    private final UuidGenerator uuidGenerator;

    public Mono<CreateAgencyResponse> createAgency(Mono<CreateAgencyRequest> request) {
        UUID agencyId = uuidGenerator.getUUID();

        return request.flatMap(createAgencyRequest -> {
            Agency agency = new Agency(agencyId, agency.getFields().getName();
            return repository.save(newAgency);    
        }).map(saved ->
            new CreateAgencyResponse(new CreateAgencyResponseData(agencyId.toString()));
        )
    }
}

您将AgencyflatMap操作中创建并将其存储在数据库中。我假设你repository的也是反应性的,所以它也应该返回Mono,因此是flatMap操作。之后,您只需要映射repository返回的任何内容(您可能希望根据对数据库的成功操作在这里有一些逻辑)来创建CreateAgencyResponse.

于 2021-11-12T21:41:40.120 回答
0

doOnNext不是执行 I/O 绑定操作(例如数据库访问)的好选择。你应该flatmap改用。此外,请查看map用于同步、一对一转换的运算符。

最终代码应如下所示:

  public Mono<CreateAgencyResponse> createAgency(Mono<CreateAgencyRequest> request) {
    return request.map(req -> new Agency(uuidGenerator.getUUID(), req.getFields().getName()))
        .flatMap(agency -> repository.save(agency))
        .map(agency -> new CreateAgencyResponse(new CreateAgencyResponseData(agency.getAgencyId())));
  }
于 2021-11-12T21:41:30.990 回答
-1

doOnNext是为了副作用,你要找的是flatMap

return request.flatMap(agency -> {
    final UUID agencyId = uuidGenerator.getUUID();
    return repository.save(new Agency(agencyId, agency.getFields().getName()))
        .thenReturn(agencyId);
}).flatMap(id -> ServerResponse.ok()
    .bodyValue(new CreateAgencyResponseData(agencyId.toString()))
    .build());

在没有编译器检查代码的情况下编写了此代码,但您应该了解它的要点。

于 2021-11-12T21:38:27.143 回答