繁体   English   中英

使用 Spring WebFlux 路由器功能时如何获取 model 属性?

[英]How to get model attributes when using Spring WebFlux router functions?

Spring WebFlux提供两种编程选项:带注释的控制器功能端点 有了第一个,我们可以使用@ModelAttribute注解将model属性从controller转移到视图(如Thymeleaf html-template),反之亦然但是,当涉及到路由器功能时,到目前为止,我刚刚弄清楚如何将 model 属性附加到ServerResponse ,但找不到将它们取回的方法。 考虑以下代码片段:

@Configuration
public class StudentsRouterFunctions {

    // inject repository
    private final StudentsCrudRepository repo;

    public StudentsRouterFunctions(StudentsCrudRepository repo) {
        this.repo = repo;
    }

    @Bean
    RouterFunction<?> routs() {
        return RouterFunctions.route()
                .GET("/students", this::showStudents)
                .POST("/students", this::saveStudent)
                .build();
    }

    // #1: GET-handler
    private Mono<ServerResponse> showStudents(ServerRequest request) {

        // set model attributes
        Map<String, Object> model = new HashMap<>();
        Mono<Student> studentsList = repo.findAll().collectList();
        Mono<Student> newStudent = Mono.just(new Student());
        model.put("students", studentsList);
        model.put("studentForm", newStudent);

        // render the view
        return ServerResponse.ok()
                .contentType(MediaType.TEXT_HTML)
                .render("students-template", model);
    }

    // #2: POST-handler
    private Mono<ServerResponse> saveStudent(ServerRequest request) {

        // and here I somehow need to get my new student object 
        // back from the view via "studentForm" model attribute

        // Student newStudent = request.getModel().get("studentForm"); 
        // !!! however, ServerRequest.getModel() method doesn't exist

        return repo.save(newStudent)
                .then(ServerResponse.status(HttpStatus.PERMANENT_REDIRECT)
                        .render("redirect:/students", new Object()));
    }

没有ServerRequest::getModel方法,但ServerRequest::bodyToMono(Class)将您的 model 所在的主体提取到Mono<T>

然后利用响应式存储库的方法ReactiveCrudRepository::save的返回类型的优势,使用Mono::flatMap返回Mono<T>

我还没有测试过,但它应该可以工作。

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))

Note the method Mono::then the element from the source so the redirected object remains as a new Object() , so you want to use Mono::map .

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));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM