Параметры маршрута
Параметр маршрута — изменяемая часть адреса. Чтобы открыть статью номер 5 на редактирование, удобно иметь адрес /posts/5: его можно сохранить в закладки и отправить коллеге. Vaadin берёт параметр из адреса, превращает в нужный тип и передаёт экрану до того, как тот появится на странице.
HasUrlParameter
Сделаем так, чтобы форма из главы про данные умела и создавать, и редактировать:
// src/main/java/com/example/blog/views/PostFormView.java (изменённые части)
@Route("posts")
@PageTitle("Статья")
public class PostFormView extends VerticalLayout implements HasUrlParameter<Long> {
private final H2 heading = new H2();
private Post post;
@Override
public void setParameter(BeforeEvent event, @OptionalParameter Long id) {
if (id == null) {
post = new Post();
post.setPublishedOn(LocalDate.now());
heading.setText("Новая статья");
} else {
post = service.findById(id).orElse(null);
if (post == null) {
event.forwardTo(PostListView.class);
return;
}
heading.setText("Редактирование");
}
binder.readBean(post);
}
}heading добавьте первым в add(...) конструктора, а сервис сохраните в поле service. Импорты из com.vaadin.flow.router: HasUrlParameter, BeforeEvent, OptionalParameter; ещё com.vaadin.flow.component.html.H2.
| Адрес | Что откроется |
|---|---|
/posts | Пустая форма «Новая статья», id равен null |
/posts/1 | Форма со статьёй «Привет, Vaadin» |
/posts/999 | Такой статьи нет — переход на список |
/posts/abc | Не число — страница «Could not navigate to 'posts/abc'» |
setParameter вызывается при каждом переходе на экран, раньше, чем экран показан. @OptionalParameter разрешает адрес без параметра.
Переход с параметром
В таблице откроем статью по двойному клику:
// src/main/java/com/example/blog/views/PostListView.java (фрагмент конструктора)
grid.addItemDoubleClickListener(event ->
getUI().ifPresent(ui -> ui.navigate(PostFormView.class, event.getItem().getId())));Двойной клик по строке «Таблицы и формы» откроет /posts/2 с заполненной формой. Второй аргумент navigate — значение параметра, Vaadin сам подставит его в адрес.
Шаблоны маршрутов
Если параметров несколько или они стоят в середине адреса, используйте шаблон. Имена параметров пишутся через двоеточие:
// src/main/java/com/example/blog/views/CommentsView.java
package com.example.blog.views;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.Route;
@Route("posts/:postId/comments")
public class CommentsView extends VerticalLayout implements BeforeEnterObserver {
private final H2 heading = new H2();
public CommentsView() {
add(heading);
}
@Override
public void beforeEnter(BeforeEnterEvent event) {
long postId = event.getRouteParameters().getLong("postId").orElseThrow();
heading.setText("Комментарии к статье " + postId);
}
}Адрес /posts/2/comments покажет «Комментарии к статье 2». В шаблоне можно ограничить параметр регулярным выражением: :postId([0-9]+).
Параметры запроса
Часть адреса после ? читается так:
// src/main/java/com/example/blog/views/CommentsView.java (фрагмент beforeEnter)
String sort = event.getLocation().getQueryParameters()
.getSingleParameter("sort").orElse("new");Для /posts/2/comments?sort=old переменная sort будет old, без параметра — new.
Частая ошибка
Параметр объявлен без @OptionalParameter, а кнопка «Новая статья» переходит без него:
// src/main/java/com/example/blog/views/PostListView.java (не работает без @OptionalParameter)
ui.navigate(PostFormView.class);Нажатие кнопки заканчивается исключением:
java.lang.IllegalArgumentException: Navigation target 'com.example.blog.views.PostFormView' requires a parameter.Пометьте параметр @OptionalParameter или передавайте значение во втором аргументе navigate.