当前位置: 首页 > 知识库问答 >
问题:

了解Spring的Web反应框架

楚羽
2023-03-14

UserController:

@RequestMapping(value = "/user", method = RequestMethod.POST)
public Mono<ResponseEntity<Integer>> createUser(@RequestBody ImUser user) {
    return Mono.just(user)
            .map(it -> {
                logger.debug("Receiving request on thread: " + Thread.currentThread().getName());
                return it;
            })
            .map(userService::create)
            .map(it -> {
                logger.debug("Sending response on thread: " + Thread.currentThread().getName());
                return ResponseEntity.status(HttpStatus.CREATED).body(it);
            })
            .mapError(DuplicateKeyException.class, e -> new SomeSpecialException(e.getMessage(), e));
}

用户服务:

public int create(ImUser user) {
    return Mono.just(user)
            .subscribeOn(Schedulers.elastic())
            .map(u -> {
                logger.debug("UserService thread: " + Thread.currentThread().getName());
                return imUserDao.insertUser(u);
            })
            .block();
}

用户道:

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
public int insertUser(ImUser user) {
    logger.debug("Insert DB on thread: " + Thread.currentThread().getName());
    return dsl.insertInto(IM_USER,IM_USER.VERSION, IM_USER.FIRST_NAME, IM_USER.LAST_NAME, IM_USER.BIRTHDATE, IM_USER.GENDER)
            .values(1, user.getFirstName(), user.getLastName(), user.getBirthdate(), user.getGender())
            .returning(IM_USER.ID)
            .fetchOne()
            .getId();
}
20:57:21,384 DEBUG         admin.UserController| Receiving request on thread: reactor-http-server-epoll-7
20:57:21,387 DEBUG            admin.UserService| UserService thread: elastic-2
20:57:21,391 DEBUG        admin.ExtendedUserDao| Insert DB on thread: elastic-2
20:57:21,393 DEBUG         tools.LoggerListener| Executing query          
...
20:57:21,401 DEBUG              tools.StopWatch| Finishing                : Total: 9.355ms, +3.355ms
20:57:21,409 DEBUG         admin.UserController| Sending response on thread: reactor-http-server-epoll-7
return userService.create(user)
            .map(it -> ResponseEntity.status(HttpStatus.CREATED).body(it))
            .mapError(DuplicateKeyException.class, e -> new SomeSpecialException(e.getMessage(), e));

但我无法实现这一点,并保持事情在正确的线程中运行。有什么方法可以在我的代码中实现这一点吗?

任何帮助都将不胜感激。谢了!

共有1个答案

暨成双
2023-03-14

服务和控制器
服务阻塞的事实是有问题的,因为在控制器中,您从映射中调用阻塞方法,而该映射没有在单独的线程上移动。这有可能阻塞所有控制器。

相反,您可以从userservice#create返回一个mono(删除末尾的块())。由于服务确保Dao方法调用是隔离的,因此问题较少。从那里,不需要在控制器中执行mono.just(user):只需调用create并直接在结果mono上启动链接操作符:

@RequestMapping(value = "/user", method = RequestMethod.POST)
public Mono<ResponseEntity<Integer>> createUser(@RequestBody ImUser user) {
    //this log as you saw was executed in the same thread as the controller method
    logger.debug("Receiving request on thread: " + Thread.currentThread().getName());
    return userService.create(user)
        .map(it -> {
            logger.debug("Sending response on thread: " + Thread.currentThread().getName());
            return ResponseEntity.status(HttpStatus.CREATED).body(it);
        })
        .mapError(DuplicateKeyException.class, e -> new SomeSpecialException(e.getMessage(), e));
}

日志记录
注意,如果您想记录某些内容,有两个比执行映射并返回更好的选项:

 类似资料:
  • 我试图使用Spring反应式WebClient将文件上传到Spring控制器。控制器非常简单,看起来像这样: 当我使用这个控制器与cURL一切正常 multipartFile转到正确的参数,其他参数进入Map。 当我尝试从WebClient做同样的事情时,我被卡住了。我的代码如下所示: 这会导致400错误 有人知道如何解决这个问题吗?

  • 根据文档,scoped bean在每个 容器中只实例化一次。例如,我有一个单例作用域的<code>UserDetails<code>bean,它包含有关用户的信息<br> 在我的main()方法中: 输出将是 因为userDetails是一个单独的bean,所以< code>ud2的第二次检索将给出与ud1相同的结果。 现在这是我的问题: 对于我的Web应用程序,我在我的中有以下bean 第一个问

  • OptionServiceImpl: 但我不知道如何以反应的方式将一个问题和它的选项结合起来。谁能提点主意吗? 更新的解决方案: 现在要获取一个问题的列表选项,我的代码如下:

  • 我试图测试Spring反应式Webclient的默认超时。为此,我创建了一个需要 10 小时才能返回响应的 rest endpoint。 我使用spring-reactive Webclient创建了一个rest客户端。但我看到,springReactiveWebclient一直在等待10个小时。 spring reactive Webclient没有任何默认超时吗?

  • Python 作为一门强大的脚本语言,能够适应快速原型和较大项目的制作,它被广泛用于 web 应用程序的开发中。 Context WSGI Web 服务网关接口 (简称为 "WSGI" ) 是一种在 Web 服务器和 Python Web 应用程序框架之间的标准接口。 通过标准化 Web 服务器和Python web 应用程序框架之间的行为和通信,WSGI 使得编写可移植的的 Python web

  • 这是一个 Tcl 的Web应用框架,旨在帮助简化 Tcl (Tool Command Language) 语言编写Web应用程序的工作。提供基本的 Web应用的功能包括:会话、用户、权限分离以及抽象的数据库接口等。目前该项目还在进一步开发中,还不足以在产品环境中使用。