Java 使用SpringWebFlux路由器函数时如何获取模型属性?

Java 使用SpringWebFlux路由器函数时如何获取模型属性?,java,spring-boot,thymeleaf,spring-webflux,project-reactor,Java,Spring Boot,Thymeleaf,Spring Webflux,Project Reactor,SpringWebFlux提供了两种编程选项的选择:带注释的控制器和功能端点。对于第一个,我们可以使用@modeldattribute注释将模型属性从控制器传输到视图(例如Thymeleafhtml模板),反之亦然。然而,当谈到路由器功能时,到目前为止,我只知道如何将模型属性附加到ServerResponse,但找不到方法将它们恢复。考虑下面的代码片段: @配置 公共课堂学生路线功能{ //注入存储库 私立期末学生储蓄回购; 公共学生路线功能(学生推荐回购){ this.repo=回购; } @

SpringWebFlux提供了两种编程选项的选择:带注释的控制器和功能端点。对于第一个,我们可以使用
@modeldattribute
注释将模型属性从控制器传输到视图(例如Thymeleafhtml模板),反之亦然。然而,当谈到路由器功能时,到目前为止,我只知道如何将模型属性附加到
ServerResponse
,但找不到方法将它们恢复。考虑下面的代码片段:

@配置
公共课堂学生路线功能{
//注入存储库
私立期末学生储蓄回购;
公共学生路线功能(学生推荐回购){
this.repo=回购;
}
@豆子
路由函数路由(){
返回RouterFunctions.route()
.GET(“/students”,this::showStudents)
.POST(“/students”,此::saveStudent)
.build();
}
//#1:获取处理程序
私人Mono showStudents(服务器请求){
//设置模型属性
映射模型=新的HashMap();
Mono studentsList=repo.findAll().collectList();
Mono newStudent=Mono.just(newStudent());
模型。放置(“学生”,学生列表);
model.put(“学生表格”,newStudent);
//渲染视图
返回ServerResponse.ok()
.contentType(MediaType.TEXT\u HTML)
.呈现(“学生模板”,模型);
}
//#2:岗位管理人员
专用Mono saveStudent(服务器请求){
//在这里,我需要得到我的新学生对象
//通过“studentForm”模型属性从视图返回
//Student newStudent=request.getModel().get(“studentForm”);
//!!!但是,ServerRequest.getModel()方法不存在
返回回购保存(newStudent)
.then(ServerResponse.status(HttpStatus.PERMANENT\u重定向)
.render(“重定向:/students”,新对象());
}

没有
ServerRequest::getModel
方法,但是它可以提取模型要
Mono
的主体

然后利用反应式存储库方法returning
Mono
using的返回类型的优势

我还没有测试出来,但它应该能工作

private Mono<ServerResponse> saveStudent(ServerRequest request) {
    return request.bodyToMono(Student.class)               // Mono<Student> (a new one)
                  .flatMap(repo::save)                     // Mono<Student> (a saved one)
                  .then(ServerResponse                     // redirect sequence
                      .status(HttpStatus.PERMANENT_REDIRECT)
                      .render("redirect:/students", new Object()));
}

// .flatMap(repo::save) is the same as .flatMap(newStudent -> repo.save(newStudent))

当我使用您的组合
bodytomano.flatMap.map
时,我得到了一个错误:不兼容的类型:推理变量R具有不兼容的边界等式约束:ServerResponse下限:Mono,因此我使用组合
bodytomano.flatMap.flatMap
。另外,
bodytomano()
在我的情况下不起作用,因为“studentForm”对象在视图中绑定到Thymeleaf的表单
th:object=“${studentForm}”
属性,因此在提交表单时,我得到一个错误:bodyType=Student不支持内容类型“application/x-www-form-urlencoded”。要解决这个问题,我必须使用
ServerRequest.formData()
method改为
ServerRequest.bodytomino()
,然后手动反序列化多值映射到Student对象,然后将其保存到存储库中。除了这些注释,我相信我可以接受您的答案。谢谢。我很高兴至少我帮助您找到了一个有效的解决方案。
private Mono<ServerResponse> saveStudent(ServerRequest request) {
    return request.bodyToMono(Student.class)               // Mono<Student> (a new one)
                  .flatMap(repo::save)                     // Mono<Student> (a saved one)
                  .map(savedStudent -> ServerResponse      // redirect sequence
                      .status(HttpStatus.PERMANENT_REDIRECT)
                      .render("redirect:/students", savedStudent));
}