首页 > 解决方案 > 从数据库中获取用户并将属性放入标签中

问题描述

我有简单的 Vaadin GUI,我想在 localhost:8080 上连接我的 Rest API:

@Route("hello")
public class EmployeeGui extends VerticalLayout {

    private final WebClient webClient = WebClient.create("http://localhost:8080");

    public EmployeeGui() {
        TextField textEmployee = new TextField("Give id of user");
        Button buttonOK = new Button("OK");
        Label label = new Label();

        buttonOK.addClickListener(buttonClickEvent -> {
            this.webClient.get()
                    .uri(uriBuilder -> uriBuilder
                            .path("/employee/{id}")
                            .build(textEmployee.getValue()))
                            .retrieve()
                            .bodyToMono(EmployeeTo.class)
                            .subscribe(emp -> {
                                   label.setText(emp.getName());
                                });
                            });

        add(textEmployee,buttonOK, label);
    }
}

在 localhost:8080 上运行我的后端应用程序,它给了我 REST API 从数据库中检索一些数据。

在文本字段中,我们可以输入用户 ID,然后单击确定按钮。之后在标签中设置用户名。不幸的是,我遇到了异常(在线label.setText(emp.getName());):

java.lang.IllegalStateException:在不锁定会话的情况下无法访问 VaadinSession 或 UI 中的状态。

我明白了,但我怎么能忽略这个问题呢?单击确定按钮后,如何放置用户 ID,然后将用户属性返回到标签?

标签: javaspring-bootvaadinspring-webflux

解决方案


该问题的直接答案是使用@PushDoc 1Doc 2)在主请求已得到响应时更新 ui(因为您webClient.get()是异步的)。您的问题的解决方法如下所示:

@Push
@Route("hello")
public class EmployeeGui extends VerticalLayout {

    private UI ui;
    private final WebClient webClient = WebClient.create("http://localhost:8080");

    public EmployeeGui() {
        TextField textEmployee = new TextField("Give id of user");
        Button buttonOK = new Button("OK");
        Label label = new Label();

        // keep instance of UI in a field,
        // and update it whenever the EmployeeGui is (re-)attached to the page
        // (important when using @PreserveOnRefresh or RouterLayout)
        addAttachListener(event -> {
            this.ui = event.getUI();
        });

        buttonOK.addClickListener(buttonClickEvent -> {
            this.webClient.get()
                    .uri(uriBuilder -> uriBuilder
                            .path("/employee/{id}")
                            .build(textEmployee.getValue()))
                            .retrieve()
                            .bodyToMono(EmployeeTo.class)
                            .subscribe(emp -> {
                                   // use ui.access to obtain lock on UI, perform updates within
                                   getUI().access(() -> label.setText(emp.getName()));
                                });
                            });

        add(textEmployee,buttonOK, label);
    }

    private UI getUI(){
        return this.ui;
    }
}

但是根据你想对你的应用程序做什么,我可以推荐使用Spring Security让用户登录,然后你可以轻松直接地访问当前用户名。


推荐阅读