Получить пользователя из БД и поместить атрибуты в метку - PullRequest
0 голосов
/ 16 июня 2020

У меня есть простой Vaadin GUI, который я хотел бы подключить к моему Rest API на локальном хосте: 8080:

@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 для извлечения некоторых данных из БД.

В текстовое поле мы можем ввести идентификатор пользователя и затем нажать кнопку ОК. После этого в ярлыке указываем имя пользователя. К сожалению, я получил исключение (в строке label.setText(emp.getName());):

java .lang.IllegalStateException: невозможно получить доступ к состоянию в VaadinSession или UI без блокировки сеанса.

Я понял это, но как я могу пропустить эту проблему? Как я могу ввести идентификатор пользователя, а затем вернуть атрибуты пользователя для метки после нажатия кнопки ОК?

Ответы [ 2 ]

1 голос
/ 17 июня 2020

Прямой ответ на вопрос использует @Push ( Do c 1 , Do c 2 ) для обновления пользовательского интерфейса, когда основной запрос уже был ответил на (потому что ваш 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 , чтобы сделать Пользователь войдет в систему, тогда у вас будет простой и прямой доступ к текущему имени пользователя.

1 голос
/ 16 июня 2020

Когда вы реагируете на запрос от вашего API, «запрос» от Vaadin уже выполнен. Если вы хотите выполнить эту работу, вам необходимо включить @Push (чтобы Ваадин мог отправлять изменения с сервера, когда они происходят) и убедитесь, что вы получаете доступ к пользовательскому интерфейсу безопасным способом (см. «Асинхронные обновления» в docs для подробностей).

Или вам на самом деле не нужно, чтобы это было asyn c и вы использовали веб-клиент блокирующим способом (так что клиент блокируется, и изменение метки происходит внутри " запрос "запускается кнопкой.

...