用反应式数据库编写业务逻辑

时间:2018-09-11 14:48:37

标签: spring mongodb reactive-programming spring-webflux

我正在编写一个反应式api,用于将通知发送到android手机。 发送通知的过程需要访问手机中的令牌代码,才能将消息推送到其中。为此,我在服务器端创建了一个端点来从电话中接收令牌。 我的问题是保存令牌,然后在上述过程中使用它。 这是TokenController,TokenService,TokenRepository和Token POJO:

@RestController
@RequestMapping("/api")
public class TokenController {

    @Autowired
    private TokenService tokenService;

    @CrossOrigin
    @RequestMapping(value = "/token",
            method = RequestMethod.POST,
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody ResponseEntity<?> newToken(@RequestBody Token token) {
        return ResponseEntity.ok(tokenService.save(token));
    }
} 

//--------------------------------------------------------------- 

@Service
public class TokenServiceImpl implements TokenService {

    @Autowired
    private TokenRepository tokenRepository;

    @Override
    public Mono<Token> save(Token token) {
        return tokenRepository.save(token);
    }
}

//--------------------------------------------------------------- 

@Repository
public interface TokenRepository extends ReactiveCrudRepository<Token, Long> { }

//---------------------------------------------------------------

@Data
@Document(collection = "token")
public class Token {

    @Id
    private Long _id;

    private Long clientCode;

    private String tokenKey; // VALUE THAT IS NEEDED ON NOTIFICATION
} 

要发送通知,我有一个通知控制器,该控制器需要访问数据库并查找令牌。读取反应式方式,我无法理解如何在通知服务中使用TokenRepository读取dababase,并使用诸如“ findById”之类的方法来检索令牌。我如何使用返回的Mono对象并获取属性“ tokenKey”?

2 个答案:

答案 0 :(得分:1)

您应该让ResponseEntity<Mono<Token>>代替Mono<ResponseEntity<Token>>

 public @ResponseBody Mono<ResponseEntity<Token>> newToken(@RequestBody Token token) {
        return tokenService.save(token)
               .map(t -> ResponseEntity.ok(t));
    }

您正在将单声道包装在一个对象中,该对象不会被订阅,因此请将其反转。

答案 1 :(得分:0)

我发现我可以将将来的结果存储在CompletableFuture中,然后在完成后存储Token对象。 这是一个示例:

CompletableFuture<Token> tokenFuture = tokenRepository.findByClientCode(notificationRequest.getClientCode()).toFuture();

Token token = tokenFuture.get(5, TimeUnit.SECONDS);

它等待5秒钟或抛出TimeoutException