Java-фреймворк для быстрой разработки корпоративных приложений. Позволяет получить полноценный пользовательский интерфейс напрямую из доменной модели – без фронтенд разработки.
В основе приложения – бесшовная интеграция трех ключевых фреймворков:
Java-фреймворк для создания веб-интерфейсов
ORM-фреймворк для работы с базой данных
Стандарт для разработки современных Java-приложений
Готовый интерфейс — без единой строки фронтенда
VHS превращает аннотированные Java-классы в готовые экраны с таблицами, формами и навигацией — без участия фронтенд-разработчика.
Боковое меню и конфигурируемая таблица с поиском, фильтрацией и действиями
Быстрый старт
Ниже приведён минимальный набор файлов, достаточный для запуска приложения с авторизацией и экраном управления пользователями.
[p:spring.datasource.url] = [s:jdbc:postgresql://localhost:5432/vhs-example]
[p:spring.datasource.username] = [s:postgres]
[p:spring.datasource.password] = [s:postgres]
[p:spring.datasource.driver-class-name] = [t:org][s:.][t:postgresql][s:.][t:Driver]
[p:spring.jpa.hibernate.naming.implicit-strategy] =
[t:org][s:.][t:hibernate][s:.][t:boot][s:.][t:model][s:.][t:naming][s:.][t:ImplicitNamingStrategyComponentPathImpl]
[p:spring.jpa.hibernate.naming.physical-strategy] =
[t:org][s:.][t:hibernate][s:.][t:boot][s:.][t:model][s:.][t:naming][s:.][t:CamelCaseToUnderscoresNamingStrategy]
[p:spring.jpa.hibernate.ddl-auto] = [m:update]
Настройка подключения к базе данных в application.properties
[a:@Theme]([s:"vhs"])
[a:@PageTitle]([s:"VHS Example"])
[a:@SpringBootApplication]
[k:public class] [t:ExampleApplication] [k:implements] [t:AppShellConfigurator] {
[k:static] [k:void] [m:main]([t:String][] [p:args]) {
[t:SpringApplication].[m:run]([t:ExampleApplication].[k:class], [p:args]);
}
}
Главный класс, с которого стартует приложение
[a:@Getter]
[a:@Setter]
[a:@Entity]
[a:@Title]([s:"Пользователь"])
[a:@EqualsAndHashCode]([p:of] = [s:"id"])
[k:public class] [t:User] [k:implements] [t:UserDetails] {
[a:@Id]
[a:@UuidGenerator]
[a:@Column]([p:updatable] = [k:false], [p:nullable] = [k:false])
[a:@Title]([s:"Идентификатор"])
[k:private] [t:UUID] [v:id];
[a:@InstanceName]
[a:@Column]([p:nullable] = [k:false])
[a:@Title]([s:"Имя"])
[a:@NotBlank]
[k:private] [t:String] [v:name];
[a:@Column]([p:unique] = [k:true], [p:updatable] = [k:false], [p:nullable] = [k:false])
[a:@Title]([s:"Логин"])
[a:@NotBlank]
[k:private] [t:String] [v:username];
[a:@Password]
[a:@Column]([p:nullable] = [k:false])
[a:@Title]([s:"Пароль"])
[a:@Size]([p:min] = [p:3])
[k:private] [t:String] [v:password];
[a:@Override]
[k:public] [t:Collection]<? [k:extends] [t:GrantedAuthority]> [m:getAuthorities]() {
[k:return] [t:Collections].[m:emptyList]();
}
}
Класс пользователя, реализующий UserDetails для аутентификации
[a:@Primary]
[a:@Service]
[k:public class] [t:UserService] [k:implements] [t:UserDetailsService] {
[a:@Autowired]
[k:private] [t:Dao] [v:dao];
[a:@PostConstruct]
[k:void] [m:init]() {
[k:if] (![v:dao].[m:load]([t:User].[k:class]).[m:exists]()) {
[m:createAdminUser]();
}
}
[a:@Override]
[k:public] [t:UserDetails] [m:loadUserByUsername]([t:String] [p:username]) [k:throws] [t:UsernameNotFoundException] {
[k:return] [v:dao].[m:load]([t:User].[k:class])
.[m:condition]([t:Condition].[m:equals]([s:"username"], [p:username]))
.[m:joinAll]()
.[m:optional]()
.[m:orElseThrow](() -> [k:new] [t:UsernameNotFoundException]([s:"Пользователь не найден"]));
}
[k:private] [k:void] [m:createAdminUser]() {
[t:User] user = [v:dao].[m:newInstance]([t:User].[k:class]);
user.[m:setName]([s:"Администратор"]);
user.[m:setUsername]([s:"admin"]);
user.[m:setPassword]([s:"admin"]);
[v:dao].[m:create](user);
}
}
Сервис аутентификации, реализующий UserDetailsService — контракт Spring Security для загрузки пользователя по логину
[a:@Route]([s:"example-app"])
[a:@MenuItem]([p:view] = [t:DataView].[k:class], [p:path] = [s:"users"],
[p:title] = [s:"Пользователи"], [p:icon] = [t:VaadinIcon].[p:USER_CARD],
[p:parameters] = [a:@Parameter]([p:clazz] = [t:User].[k:class]))
[k:public class] [t:MainView] [k:extends] [t:VhsLayout] {
}
Главный экран и структура навигационного меню
Подключить в свой проект
Версия 0.1.0 пока не опубликована в Maven Central. Когда будет готово –
просто добавьте зависимость в
pom.xml.
Следите за релизами и обновлениями в нашем Telegram-канале.
[c:<!-- VHS.framework -->]
<[v:dependency]>
<[v:groupId]>ru.vhsframework</[v:groupId]>
<[v:artifactId]>vhs</[v:artifactId]>
<[v:version]>0.1.0</[v:version]>
</[v:dependency]>
Введение
Общие сведения
VHS — интеграционный фреймворк, который объединяет Vaadin (UI), Hibernate (ORM) и Spring (IoC/DI) в единую согласованную архитектуру для быстрой разработки бизнес-приложений на Java.
Писать HTML, XML-шаблоны, CSS-стили или JavaScript не нужно — UI-экраны генерируются автоматически на основе Java-классов и уже включают все необходимые настройки. Никакого генерируемого кода, который нужно поддерживать вручную.
Библиотека имеет богатый набор готовых компонентов для построения сложных UI: с формами, фильтрами, диалогами и валидацией — не выходя за пределы Java-кода. При необходимости каждый компонент можно расширить или заменить собственной реализацией — VHS не ограничивает вас в кастомизации.
Требования
Убедитесь, что в вашем проекте подключены:
- Java 17+
- Maven или Gradle
- Spring Boot 3.x
- Vaadin 24.x
- Любая реляционная БД, поддерживаемая Hibernate
Сущности
Общие понятия
Сущность — основной строительный блок любого приложения. Это обычный Java-класс,
аннотированный @Entity, поля которого фреймворк автоматически
преобразует в UI-компоненты: колонки таблиц, поля форм, фильтры.
Никакой дополнительной конфигурации не требуется — достаточно описать класс,
и VHS сформирует полноценный CRUD-экран.
Базовый пример
Минимальная сущность требует только аннотации @Entity и поля с
@Id. Аннотации VHS добавляются по мере необходимости.
[a:@Entity]
[a:@Title]([s:"Пользователь"])
[k:public class] [t:User] {
[a:@Id]
[a:@GeneratedValue]([p:strategy] = [t:GenerationType].[p:IDENTITY])
[k:private] [t:Long] [v:id];
[a:@Title]([s:"Имя"])
[a:@NotBlank]
[k:private] [t:String] [v:firstName];
[a:@Title]([s:"Фамилия"])
[a:@NotBlank]
[k:private] [t:String] [v:lastName];
[a:@Title]([s:"Email"])
[a:@Email]
[a:@Column]([p:unique] = [k:true])
[k:private] [t:String] [v:email];
[a:@Title]([s:"Возраст"])
[a:@Min]([p:0]) [a:@Max]([p:100])
[k:private] [k:int] [v:age];
[a:@InstanceName]
[k:public] [t:String] [m:getFullName]() {
[k:return] [v:firstName] + [s:" "] + [v:lastName];
}
}
Интерфейсы сущностей
VHS предоставляет ряд интерфейсов, которые сущность может реализовать для получения дополнительного поведения в UI — без какой-либо ручной настройки компонентов.
HasZoneId
Если сущность реализует HasZoneId, фреймворк будет отображать
все поля даты и времени в часовом поясе, возвращаемом методом getZoneId().
Это удобно, например, когда у каждого пользователя или филиала свой часовой пояс.
HasAvatar
Реализация HasAvatar позволяет фреймворку отображать аватар пользователя
в интерфейсе приложения. Если метод getFile() возвращает null,
фреймворк автоматически выводит аббревиатуру из имени пользователя на цветном фоне.
Поддерживаемые типы данных
Типы данных
VHS поддерживает широкий набор Java-типов — от примитивов до коллекций и встраиваемых объектов. Каждый тип автоматически получает подходящий UI-компонент.
| Тип | Описание |
|---|---|
Boolean / boolean |
Логическое значение (истина / ложь) |
| Символьные | |
Character / char |
Одиночный символ Unicode |
String |
Строка символов |
| Числовые | |
Byte / byte |
Целое число от -128 до 127 |
Short / short |
Целое число от -32 768 до 32 767 |
Integer / int |
Целое число от -2³¹ до 2³¹-1 |
Long / long |
Целое число от -2⁶³ до 2⁶³-1 |
Float / float |
Число с плавающей точкой одинарной точности |
Double / double |
Число с плавающей точкой двойной точности |
BigInteger |
Целое число произвольной точности |
BigDecimal |
Десятичное число произвольной точности |
| Дата и время | |
Date |
Дата и время (legacy) |
Calendar |
Дата и время (legacy) |
Instant |
Момент времени в UTC |
LocalDate |
Дата без времени и часового пояса |
LocalDateTime |
Дата и время без часового пояса |
LocalTime |
Время без даты и часового пояса |
MonthDay |
Месяц и день без года |
OffsetDateTime |
Дата и время со смещением от UTC |
OffsetTime |
Время со смещением от UTC |
Year |
Год |
YearMonth |
Год и месяц |
ZonedDateTime |
Дата и время с полным часовым поясом |
| Дополнительные | |
UUID |
Уникальный идентификатор (128 бит) |
Period |
Промежуток между датами в годах, месяцах и днях |
Duration |
Продолжительность в секундах и наносекундах |
ZoneId |
Идентификатор часового пояса (например, Europe/Moscow) |
| Перечисление | |
Enum |
Значение из фиксированного набора констант |
| Ссылка на сущность | |
Entity |
Ссылка на связанный JPA-объект |
| Файл | |
File |
Ссылка на загруженный файл |
| Коллекции | |
List<Enum> |
Коллекция enum-значений |
List<Entity> |
Коллекция связанных JPA-сущностей |
List<File> |
Коллекция загруженных файлов |
| Встраиваемые объекты | |
Embedded |
Группа полей, сохраняемая в таблице владельца |
| Ассоциативный массив | |
Map<K, V> |
Коллекция пар «ключ — значение» |
Аннотации JPA
VHS не ограничивает использование JPA — все стандартные аннотации маппинга поддерживаются в полном объёме. Таблица служит краткой памяткой по аннотациям маппинга.
| Группа | Аннотация | Описание |
|---|---|---|
| Идентификатор | @Id |
Первичный ключ сущности |
@EmbeddedId |
Составной первичный ключ через встраиваемый объект | |
| Версия | @Version |
Поле версии для оптимистичной блокировки |
| Аудит | @CreatedBy |
Кто создал запись |
@CreatedDate |
Дата создания записи | |
@LastModifiedBy |
Кто последний изменил запись | |
@LastModifiedDate |
Дата последнего изменения записи | |
| Простое поле | @Column |
Настройка отображения поля в колонку таблицы |
| Перечисления | @Enumerated |
Способ хранения перечисления в БД |
@ElementCollection |
Коллекция простых значений или перечислений | |
@CollectionTable |
Настройка таблицы для хранения коллекции | |
| Ссылка на сущность | @JoinColumn |
Настройка колонки внешнего ключа |
@OneToOne |
Связь «один к одному» | |
@ManyToOne |
Связь «многие к одному» | |
@MapsId |
Использует внешний ключ связи как первичный ключ сущности | |
| Список объектов | @OneToMany |
Связь «один ко многим» |
@ManyToMany |
Связь «многие ко многим» | |
@JoinTable |
Настройка промежуточной таблицы связи | |
| Встраиваемый объект | @Embeddable |
Класс, чьи поля встраиваются в таблицу владельца |
@Embedded |
Встраивает поля дочернего объекта в таблицу владельца | |
| Ассоциативный массив | @MapKey |
Ключ map — поле связанной сущности |
@MapKeyColumn |
Ключ map — простое значение, настройка колонки | |
@MapKeyJoinColumn |
Ключ map — ссылка на другую сущность | |
@MapKeyJoinColumns |
Ключ map — сущность с составным первичным ключом | |
@MapKeyEnumerated |
Ключ map — перечисление, способ хранения | |
@MapKeyTemporal |
Ключ map — дата или время, способ хранения |
Валидация
Ограничения на значения полей задаются стандартными аннотациями Bean Validation — VHS подхватывает их и отображает ошибки прямо на форме.
| Аннотация | Описание |
|---|---|
@NotNull |
Значение обязательно для заполнения |
@Null |
Значение должно отсутствовать |
| Логические | |
@AssertTrue |
Значение должно быть true |
@AssertFalse |
Значение должно быть false |
| Строки | |
@NotBlank |
Строка не должна быть пустой или состоять только из пробелов |
@NotEmpty |
Строка или коллекция не должна быть пустой |
@Email |
Строка должна быть валидным адресом электронной почты |
@Pattern |
Строка должна соответствовать регулярному выражению |
@Size |
Длина строки или размер коллекции должны быть в заданном диапазоне |
| Числовые | |
@Digits |
Число должно соответствовать заданному формату цифр |
@Min |
Число должно быть не меньше указанного значения |
@Max |
Число должно быть не больше указанного значения |
@DecimalMin |
Десятичное число должно быть не меньше указанного значения |
@DecimalMax |
Десятичное число должно быть не больше указанного значения |
@Positive |
Число должно быть строго положительным |
@PositiveOrZero |
Число должно быть положительным или равным нулю |
@Negative |
Число должно быть строго отрицательным |
@NegativeOrZero |
Число должно быть отрицательным или равным нулю |
| Дата и время | |
@Past |
Дата должна быть в прошлом |
@PastOrPresent |
Дата должна быть в прошлом или настоящем |
@Future |
Дата должна быть в будущем |
@FutureOrPresent |
Дата должна быть в будущем или настоящем |
| Коллекции и Maps | |
@NotEmpty |
Коллекция или ассоциативный массив не должен быть пустой |
@Size |
Размер коллекции или ассоциативного массива должен быть в заданном диапазоне |
Настройка форм
Аннотации отображения полей
Фреймворк автоматически генерирует формы на основе полей класса. Управлять их отображением и поведением можно с помощью аннотаций, которые размещаются над нужным полем или классом.
| Аннотация | Описание |
|---|---|
@Title |
Задает отображаемое название поля или класса в форме.
|
@Placeholder |
Задает подсказку внутри поля, исчезающую при вводе.
|
@HelperText |
Отображает вспомогательный текст под полем.
|
@Tooltip |
Отображает всплывающую подсказку при наведении.
|
@Mask |
Накладывает маску ввода на поле. Использует библиотеку imaskjs.
|
@Password |
Скрывает введенное значение и автоматически хэширует его через PasswordEncoder
перед сохранением.
|
@Url |
Добавляет кнопку перехода на форме и отображает кликабельное значение в таблице.
|
@GridColumns |
Задает список колонок, отображаемых в табличном представлении. Можно указать как
на классе, так и на поле.
|
Текстовое представление сущностей
По умолчанию все перечисления и сущности на форме отображаются с использованием
toString. Вы можете переопределить это поведение, указав данную
аннотацию над полем или методом. Такой метод может принимать любые Spring-бины.
| Аннотация | Примеры |
|---|---|
@InstanceName |
|
Условное поведение полей (SpEL)
Для описания условий используется Spring Expression Language (SpEL). Выражение вычисляется в контексте текущей сущности — поля класса доступны по имени напрямую.
Обычно зависимые переменные, указанные в условии, определяются автоматически. Но вы можете
указать их явно в аннотации в параметре dependentFields.
| Аннотация | Описание |
|---|---|
@ReadOnlyWhen |
Аннотированное поле будет отображаться в режиме readonly при
выполнении заданного условия
|
@DisabledWhen |
Аннотированное поле будет отображаться в режиме disabled при
выполнении заданного условия
|
@VisibleWhen |
Аннотированное поле будет отображаться на форме только при выполнении заданного
условия
|
@OnValueChange |
Позволяет выполнить SpEL-выражение при изменении значения в поле
|
Кастомизация компонентов
В реализуемом классе быть конструктор, принимающий 1 параметр наследуемый от MetaField<T,
V>. Сама аннотация может быть указана как над полем, так и над классом-типом — в
последнем случае применяется ко всем полям этого типа.
Отображение на форме
Позволяет заменить стандартный компонент поля на кастомный.
[a:@VaadinField]([t:PaymentTypeField].[k:class])
[k:private] [t:PaymentType] [v:type];
[a:@RequiredArgsConstructor]
[k:public] [k:class] [t:PaymentTypeField]<[t:T]> [k:extends] [t:RadioButtonGroup]<[t:PaymentType]> {
[k:private] [k:final] [t:EnumMetaField]<[t:T], [t:PaymentType]> [v:field];
[a:@PostConstruct]
[k:void] [m:init]() {
[m:setItems]([v:field].[m:getEnumConstants]());
[m:setItemLabelGenerator]([t:PaymentType]::[m:getLabel]);
[m:addThemeVariants]([t:RadioGroupVariant].[p:LUMO_VERTICAL]);
}
}
Отображение в таблице
Задаёт кастомный рендерер для ячеек табличного представления.
[a:@VaadinRenderer]([t:PaymentTypeRenderer].[k:class])
[k:private] [t:PaymentType] [v:type];
[a:@Component]
[a:@PrototypeScope]
[k:public] [k:class] [t:PaymentTypeRenderer]<[t:T]> [k:extends] [t:ComponentRenderer]<[t:Span], [t:T]> {
[k:public] [m:PaymentTypeRenderer]([t:EnumMetaField]<[t:T], [t:PaymentType]> [p:field]) {
[k:super]([p:entity] -> {
[t:PaymentType] type = [p:field].[m:getGetter]().[m:apply]([p:entity]);
[k:return] [k:new] [t:Span](type != [k:null] ? type.[m:getLabel]() : [s:""]);
}
}
}
Валидация
Подключает кастомный валидатор к полю формы.
[a:@VaadinValidator]([t:PaymentTypeValidator].[k:class])
[k:private] [t:PaymentType] [v:type];
[a:@Component]
[a:@PrototypeScope]
[k:public] [k:class] [t:PaymentTypeValidator]<[t:T]>
[k:extends] [t:BaseValidator]<[t:T], [t:PaymentType], [t:EnumMetaField]<[t:T], [t:PaymentType]>> {
[k:public] [m:PaymentTypeValidator]([t:EnumMetaField]<[t:T], [t:PaymentType]> [p:field]) {
[k:super]([p:field]);
}
[a:@Override]
[k:public] [k:void] [m:bindTo]([t:Binder].[t:BindingBuilder]<[t:T], [t:PaymentType]> [p:bindingBuilder]) {
[k:super].[m:bindTo]([p:bindingBuilder]);
[p:bindingBuilder].[m:withValidator]([p:type] -> [p:type] != [t:PaymentType].[p:CASH],
[s:"Оплата наличными недоступна"]);
}
}
Доступ к данным
Общие понятия
VHS использует EntityManager для сохранения сущностей через
встроенный компонент Dao.
При необходимости вы можете определить и использовать стандартные CRUD-репозитории — так же, как это принято в Spring Data.
Создание сущностей
Если ваша сущность содержит метод с аннотацией @PostConstruct, используйте
dao.newInstance() для корректной инициализации. Такой метод может принимать
любое количество Spring-бинов.
[k:public] [k:class] [t:User] {
[k:private] [t:String] [v:name];
[a:@PostConstruct]
[k:void] [m:init]([t:MyService] [p:service]) {
[k:this].[v:name] = [p:service].[m:randomName]();
}
}
[c:// Создание сущности с @PostConstruct]
[t:User] a = [v:dao].[m:newInstance]([t:User].[k:class]);
[c:// Создание сущности без @PostConstruct]
[t:User] b = [k:new] [t:User]();
Сохранение сущностей
Если ваша сущность реализует Persistable или EntityInformation
либо содержит поле @Id / @Version — вы можете использовать
универсальный метод save. Он автоматически определит состояние сущности и
вызовет persist или merge.
Подробнее о стратегиях определения состояния сущности смотрите в документации Spring Data JPA.
[c:// Сохранение сущности]
[v:dao].[m:save]([p:entity]);
Как альтернатива, вы можете явно указать операцию:
[c:// Создание новой сущности]
[v:dao].[m:create]([p:entity]);
[c:// Обновление существующей сущности]
[v:dao].[m:update]([p:entity]);
[c:// Удаление существующей сущности]
[v:dao].[m:delete]([p:entity]);
Выборка данных
Dao предоставляет fluent API для построения запросов непосредственно из
Java-кода — без написания JPQL или SQL вручную.
Запрос строится цепочкой методов: фильтрация, подгрузка связанных сущностей, сортировка и ограничение выборки. В конце вызывается терминальный метод для получения списка или одной записи.
[t:List]<[t:Customer]> customers = [v:dao].[m:load]([t:Customer].[k:class])
.[m:condition]([t:Condition].[m:startsWith]([s:"name"], [s:"Алекс"]))
.[m:condition]([t:Condition].[m:isNotTrue]([s:"blocked"]))
.[m:condition]([t:Condition].[m:or](
[t:Condition].[m:greaterThanOrEquals]([s:"age"], [p:18]),
[t:Condition].[m:in]([s:"id"], [t:List].[m:of]([p:1], [p:2], [p:3]))))
.[m:join]([s:"orders"])
.[m:limit]([p:10])
.[m:orderBy]([s:"id"], [t:Sort].[t:Direction].[p:ASC])
.[m:list]();
Условия выборки
Полный список условий, доступных для построения запросов с использованием
Condition:
| Метод | Описание |
|---|---|
equals(field, value) |
Поле равно значению |
notEquals(field, value) |
Поле не равно значению |
isNull(field) |
Поле равно null |
isNotNull(field) |
Поле не равно null |
in(field, values) |
Поле входит в список значений |
notIn(field, values) |
Поле не входит в список значений |
| Булевые | |
isTrue(field) |
Поле равно true |
isNotTrue(field) |
Поле не равно true |
isFalse(field) |
Поле равно false |
isNotFalse(field) |
Поле не равно false |
| Сравнение чисел и дат | |
lessThan(field, value) |
Поле меньше значения |
greaterThan(field, value) |
Поле больше значения |
lessThanOrEquals(field, value) |
Поле меньше или равно значению |
greaterThanOrEquals(field, value) |
Поле больше или равно значению |
between(field, low, high) |
Поле находится в диапазоне от low до high включительно
|
notBetween(field, low, high) |
Поле находится вне диапазона от low до high |
| Строки | |
equalsIgnoreCase(field, string) |
Поле равно значению без учёта регистра |
notEqualsIgnoreCase(field, string) |
Поле не равно значению без учёта регистра |
isEmpty(field) |
Поле пустое или null |
isNotEmpty(field) |
Поле не пустое и не null |
isBlank(field) |
Поле пустое, null или состоит только из пробелов |
isNotBlank(field) |
Поле не пустое, не null и содержит символы помимо пробелов |
contains(field, string) |
Поле содержит подстроку |
notContains(field, string) |
Поле не содержит подстроку |
containsIgnoreCase(field, string) |
Поле содержит подстроку без учёта регистра |
notContainsIgnoreCase(field, string) |
Поле не содержит подстроку без учёта регистра |
startsWith(field, string) |
Поле начинается с указанной строки |
notStartsWith(field, string) |
Поле не начинается с указанной строки |
startsWithIgnoreCase(field, string) |
Поле начинается с указанной строки без учёта регистра |
notStartsWithIgnoreCase(field, string) |
Поле не начинается с указанной строки без учёта регистра |
endsWith(field, string) |
Поле заканчивается на указанную строку |
notEndsWith(field, string) |
Поле не заканчивается на указанную строку |
endsWithIgnoreCase(field, string) |
Поле заканчивается на указанную строку без учёта регистра |
notEndsWithIgnoreCase(field, string) |
Поле не заканчивается на указанную строку без учёта регистра |
like(field, pattern) |
Поле соответствует паттерну like |
notLike(field, pattern) |
Поле не соответствует паттерну like |
likeIgnoreCase(field, pattern) |
Поле соответствует паттерну без учёта регистра |
notLikeIgnoreCase(field, pattern) |
Поле не соответствует паттерну без учёта регистра |
| Коллекции | |
containsAny(field, values) |
Поле содержит хотя бы одно из значений |
containsAll(field, values) |
Поле содержит все указанные значения |
containsNone(field, values) |
Поле не содержит ни одного из указанных значений |
isEmpty(field) |
Коллекция пуста |
isNotEmpty(field) |
Коллекция не пуста |
| Логические | |
and(conditions) |
Объединяет условия логическим и |
or(conditions) |
Объединяет условия логическим или |
not(condition) |
Инвертирует условие |
Работа с файлами
Общие сведения
Для работы с файлами необходимо создать собственную сущность, реализующую интерфейс
io.vhs.storage.File. После этого такой тип можно использовать в любых
сущностях
как обычное поле или коллекцию файлов. VHS автоматически создаст компонент загрузки,
предпросмотр, скачивание и удаление файлов.
Описание сущности файла
Минимальное требование — реализовать интерфейс File. Остальная структура
сущности определяется приложением и используемым способом хранения.
[a:@Entity]
[k:public class] [t:MyFile] [k:implements] [t:File] {
[c:...]
}
Использование собственного хранилища
По умолчанию VHS использует LocalFileStorage, сохраняющий файлы в локальной
файловой системе. При необходимости можно указать собственную реализацию хранилища с
помощью аннотации @FileStorage.
Аннотация может быть размещена как над классом файла, так и над отдельным полем:
[a:@Entity]
[a:@FileStorage]([t:MyFileStorage].[k:class])
[k:public class] [t:MyFile] [k:implements] [t:File] {
[c:...]
}
[a:@FileStorage]([t:MyFileStorage].[k:class])
[k:private] [t:MyFile] [v:file];
Аннотация, указанная над полем, имеет приоритет над аннотацией, размещённой на классе. Это позволяет использовать разные хранилища для одной и той же сущности файла в зависимости от конкретного поля.
Пользовательский интерфейс
Навигация и меню
Для определения структуры приложения создайте класс, унаследованный от
VhsLayout,
и пометьте его аннотацией @Route. Навигационное меню формируется с помощью
аннотаций @MenuItem, размещённых на этом же классе.
[a:@Route]([s:"/my-app"])
[a:@MenuItem]([p:view] = [t:DataView].[k:class], [p:path] = [s:"/users"],
[p:title] = [s:"Пользователи"], [p:icon] = [t:VaadinIcon].[p:USER_CARD],
[p:parameters] = [a:@Parameter]([p:clazz] = [t:User].[k:class]))
[k:public class] [t:MainView] [k:extends] [t:VhsLayout] {
}
Каждый @MenuItem описывает один пункт меню. Доступные параметры:
| Параметр | Описание |
|---|---|
view |
Компонент-представление, которое будет открыто при переходе |
path |
URL-путь для навигации |
title |
Отображаемое название пункта меню |
icon |
Иконка пункта меню из набора VaadinIcon |
parameters |
Массив параметров, передаваемый в представление |
subMenu |
Вложенные пункты меню @SubMenuItem |
Ограничение доступа
Если вы определяете кастомный компонент, вы можете ограничить к нему доступ с помощью стандартных привычных аннотаций:
| Аннотация | Описание |
|---|---|
@PreAuthorize |
Проверка условия доступа через SpEL |
@Secured |
Ограничение доступа по названию роли |
@RolesAllowed |
Ограничение доступа по роли в стиле Jakarta EE |
[a:@PreAuthorize]([s:"hasRole('ADMIN')"])
[k:public class] [t:AdminView] [k:extends] [t:Div] {
[c:...]
}
Развертывание приложения
Общие сведения
С точки зрения развёртывания VHS не вносит никаких изменений — приложение собирается и запускается как обычное Vaadin-приложение на Spring Boot. Подробнее см. в документации Vaadin.
404
Not Found
Как вы здесь оказались?
Политика в отношении обработки персональных данных
-
Общие положения
Настоящая политика обработки персональных данных составлена в соответствии с требованиями Федерального закона от 27.07.2006 № 152-ФЗ «О персональных данных» (далее — Закон о персональных данных) и определяет порядок обработки персональных данных и меры по обеспечению безопасности персональных данных, предпринимаемые Хохловым Александром Николаевичем (далее — Оператор).
- Оператор ставит своей важнейшей целью и условием осуществления своей деятельности соблюдение прав и свобод человека и гражданина при обработке его персональных данных, в том числе защиты прав на неприкосновенность частной жизни, личную и семейную тайну.
- Настоящая политика Оператора в отношении обработки персональных данных (далее — Политика) применяется ко всей информации, которую Оператор может получить о посетителях веб-сайта https://vhsframework.ru.
-
Основные понятия, используемые в Политике
- Автоматизированная обработка персональных данных — обработка персональных данных с помощью средств вычислительной техники.
- Блокирование персональных данных — временное прекращение обработки персональных данных (за исключением случаев, если обработка необходима для уточнения персональных данных).
- Веб-сайт — совокупность графических и информационных материалов, а также программ для ЭВМ и баз данных, обеспечивающих их доступность в сети интернет по сетевому адресу https://vhsframework.ru.
- Информационная система персональных данных — совокупность содержащихся в базах данных персональных данных и обеспечивающих их обработку информационных технологий и технических средств.
- Обезличивание персональных данных — действия, в результате которых невозможно определить без использования дополнительной информации принадлежность персональных данных конкретному Пользователю или иному субъекту персональных данных.
- Обработка персональных данных — любое действие (операция) или совокупность действий (операций), совершаемых с использованием средств автоматизации или без использования таких средств с персональными данными, включая сбор, запись, систематизацию, накопление, хранение, уточнение (обновление, изменение), извлечение, использование, передачу (распространение, предоставление, доступ), обезличивание, блокирование, удаление, уничтожение персональных данных.
- Оператор — государственный орган, муниципальный орган, юридическое или физическое лицо, самостоятельно или совместно с другими лицами организующие и/или осуществляющие обработку персональных данных, а также определяющие цели обработки персональных данных, состав персональных данных, подлежащих обработке, действия (операции), совершаемые с персональными данными.
- Персональные данные — любая информация, относящаяся прямо или косвенно к определенному или определяемому Пользователю веб-сайта https://vhsframework.ru.
- Персональные данные, разрешенные субъектом персональных данных для распространения, — персональные данные, доступ неограниченного круга лиц к которым предоставлен субъектом персональных данных путем дачи согласия на обработку персональных данных, разрешенных субъектом персональных данных для распространения в порядке, предусмотренном Законом о персональных данных (далее — персональные данные, разрешенные для распространения).
- Пользователь — любой посетитель веб-сайта https://vhsframework.ru.
- Предоставление персональных данных — действия, направленные на раскрытие персональных данных определенному лицу или определенному кругу лиц.
- Распространение персональных данных — любые действия, направленные на раскрытие персональных данных неопределенному кругу лиц (передача персональных данных) или на ознакомление с персональными данными неограниченного круга лиц, в том числе обнародование персональных данных в средствах массовой информации, размещение в информационно-телекоммуникационных сетях или предоставление доступа к персональным данным каким-либо иным способом.
- Трансграничная передача персональных данных — передача персональных данных на территорию иностранного государства органу власти иностранного государства, иностранному физическому или иностранному юридическому лицу.
- Уничтожение персональных данных — любые действия, в результате которых персональные данные уничтожаются безвозвратно с невозможностью дальнейшего восстановления содержания персональных данных в информационной системе персональных данных и/или уничтожаются материальные носители персональных данных.
-
Основные права и обязанности Оператора
-
Оператор имеет право:
- получать от субъекта персональных данных достоверные информацию и/или документы, содержащие персональные данные;
- в случае отзыва субъектом персональных данных согласия на обработку персональных данных, а также направления обращения с требованием о прекращении обработки персональных данных, Оператор вправе продолжить обработку персональных данных без согласия субъекта персональных данных при наличии оснований, указанных в Законе о персональных данных;
- самостоятельно определять состав и перечень мер, необходимых и достаточных для обеспечения выполнения обязанностей, предусмотренных Законом о персональных данных и принятыми в соответствии с ним нормативными правовыми актами, если иное не предусмотрено Законом о персональных данных или другими федеральными законами.
-
Оператор обязан:
- предоставлять субъекту персональных данных по его просьбе информацию, касающуюся обработки его персональных данных;
- организовывать обработку персональных данных в порядке, установленном действующим законодательством РФ;
- отвечать на обращения и запросы субъектов персональных данных и их законных представителей в соответствии с требованиями Закона о персональных данных;
- сообщать в уполномоченный орган по защите прав субъектов персональных данных по запросу этого органа необходимую информацию в течение 10 дней с даты получения такого запроса;
- публиковать или иным образом обеспечивать неограниченный доступ к настоящей Политике в отношении обработки персональных данных;
- принимать правовые, организационные и технические меры для защиты персональных данных от неправомерного или случайного доступа к ним, уничтожения, изменения, блокирования, копирования, предоставления, распространения персональных данных, а также от иных неправомерных действий в отношении персональных данных;
- прекратить передачу (распространение, предоставление, доступ) персональных данных, прекратить обработку и уничтожить персональные данные в порядке и случаях, предусмотренных Законом о персональных данных;
- исполнять иные обязанности, предусмотренные Законом о персональных данных.
-
Оператор имеет право:
-
Основные права и обязанности субъектов персональных данных
-
Субъекты персональных данных имеют право:
- получать информацию, касающуюся обработки его персональных данных, за исключением случаев, предусмотренных федеральными законами. Сведения предоставляются субъекту персональных данных Оператором в доступной форме, и в них не должны содержаться персональные данные, относящиеся к другим субъектам персональных данных, за исключением случаев, когда имеются законные основания для раскрытия таких персональных данных. Перечень информации и порядок ее получения установлен Законом о персональных данных;
- требовать от оператора уточнения его персональных данных, их блокирования или уничтожения в случае, если персональные данные являются неполными, устаревшими, неточными, незаконно полученными или не являются необходимыми для заявленной цели обработки, а также принимать предусмотренные законом меры по защите своих прав;
- выдвигать условие предварительного согласия при обработке персональных данных в целях продвижения на рынке товаров, работ и услуг;
- на отзыв согласия на обработку персональных данных, а также на направление требования о прекращении обработки персональных данных;
- обжаловать в уполномоченный орган по защите прав субъектов персональных данных или в судебном порядке неправомерные действия или бездействие Оператора при обработке его персональных данных;
- на осуществление иных прав, предусмотренных законодательством РФ.
-
Субъекты персональных данных обязаны:
- предоставлять Оператору достоверные данные о себе;
- сообщать Оператору об уточнении (обновлении, изменении) своих персональных данных.
- Лица, передавшие Оператору недостоверные сведения о себе, либо сведения о другом субъекте персональных данных без согласия последнего, несут ответственность в соответствии с законодательством РФ.
-
Субъекты персональных данных имеют право:
-
Принципы обработки персональных данных
- Обработка персональных данных осуществляется на законной и справедливой основе.
- Обработка персональных данных ограничивается достижением конкретных, заранее определенных и законных целей. Не допускается обработка персональных данных, несовместимая с целями сбора персональных данных.
- Не допускается объединение баз данных, содержащих персональные данные, обработка которых осуществляется в целях, несовместимых между собой.
- Обработке подлежат только персональные данные, которые отвечают целям их обработки.
- Содержание и объем обрабатываемых персональных данных соответствуют заявленным целям обработки. Не допускается избыточность обрабатываемых персональных данных по отношению к заявленным целям их обработки.
- При обработке персональных данных обеспечивается точность персональных данных, их достаточность, а в необходимых случаях и актуальность по отношению к целям обработки персональных данных. Оператор принимает необходимые меры и/или обеспечивает их принятие по удалению или уточнению неполных или неточных данных.
- Хранение персональных данных осуществляется в форме, позволяющей определить субъекта персональных данных, не дольше, чем этого требуют цели обработки персональных данных, если срок хранения персональных данных не установлен федеральным законом, договором, стороной которого, выгодоприобретателем или поручителем по которому является субъект персональных данных. Обрабатываемые персональные данные уничтожаются либо обезличиваются по достижении целей обработки или в случае утраты необходимости в достижении этих целей, если иное не предусмотрено федеральным законом.
-
Цели обработки персональных данных
Цель обработки Предоставление доступа Пользователю к сервисам, информации и/или материалам, содержащимся на веб-сайте Персональные данные - фамилия, имя, отчество
- электронный адрес
- номера телефонов
Правовые основания Федеральный закон «Об информации, информационных технологиях и о защите информации» от 27.07.2006 N 149-ФЗ Виды обработки
персональных данных- Сбор, запись, систематизация, накопление, хранение, уничтожение и обезличивание персональных данных
- Отправка информационных писем на адрес электронной почты
-
Условия обработки персональных данных
- Обработка персональных данных осуществляется с согласия субъекта персональных данных на обработку его персональных данных.
- Обработка персональных данных необходима для достижения целей, предусмотренных международным договором Российской Федерации или законом, для осуществления возложенных законодательством Российской Федерации на оператора функций, полномочий и обязанностей.
- Обработка персональных данных необходима для осуществления правосудия, исполнения судебного акта, акта другого органа или должностного лица, подлежащих исполнению в соответствии с законодательством Российской Федерации об исполнительном производстве.
- Обработка персональных данных необходима для исполнения договора, стороной которого либо выгодоприобретателем или поручителем по которому является субъект персональных данных, а также для заключения договора по инициативе субъекта персональных данных или договора, по которому субъект персональных данных будет являться выгодоприобретателем или поручителем.
- Обработка персональных данных необходима для осуществления прав и законных интересов оператора или третьих лиц либо для достижения общественно значимых целей при условии, что при этом не нарушаются права и свободы субъекта персональных данных.
- Осуществляется обработка персональных данных, доступ неограниченного круга лиц к которым предоставлен субъектом персональных данных либо по его просьбе (далее — общедоступные персональные данные).
- Осуществляется обработка персональных данных, подлежащих опубликованию или обязательному раскрытию в соответствии с федеральным законом.
-
Порядок сбора, хранения, передачи и других видов обработки персональных данных
Безопасность персональных данных, которые обрабатываются Оператором, обеспечивается путем реализации правовых, организационных и технических мер, необходимых для выполнения в полном объеме требований действующего законодательства в области защиты персональных данных.
- Оператор обеспечивает сохранность персональных данных и принимает все возможные меры, исключающие доступ к персональным данным неуполномоченных лиц.
- Персональные данные Пользователя никогда, ни при каких условиях не будут переданы третьим лицам, за исключением случаев, связанных с исполнением действующего законодательства либо в случае, если субъектом персональных данных дано согласие Оператору на передачу данных третьему лицу для исполнения обязательств по гражданско-правовому договору.
-
В случае выявления неточностей в персональных данных, Пользователь может актуализировать
их самостоятельно, путем направления Оператору
уведомление на адрес электронной почты Оператора
mail@vhsframework.ruс пометкой «Актуализация персональных данных». - Срок обработки персональных данных определяется достижением целей, для которых были собраны персональные данные, если иной срок не предусмотрен договором или действующим законодательством.
-
Пользователь может в любой момент отозвать свое согласие на обработку персональных
данных, направив Оператору уведомление посредством
электронной почты на электронный адрес Оператора
mail@vhsframework.ruс пометкой «Отзыв согласия на обработку персональных данных». - Вся информация, которая собирается сторонними сервисами, в том числе платежными системами, средствами связи и другими поставщиками услуг, хранится и обрабатывается указанными лицами (Операторами) в соответствии с их Пользовательским соглашением и Политикой конфиденциальности. Субъект персональных данных и/или с указанными документами. Оператор не несет ответственность за действия третьих лиц, в том числе указанных в настоящем пункте поставщиков услуг.
- Установленные субъектом персональных данных запреты на передачу (кроме предоставления доступа), а также на обработку или условия обработки (кроме получения доступа) персональных данных, разрешенных для распространения, не действуют в случаях обработки персональных данных в государственных, общественных и иных публичных интересах, определенных законодательством РФ.
- Оператор при обработке персональных данных обеспечивает конфиденциальность персональных данных.
- Оператор осуществляет хранение персональных данных в форме, позволяющей определить субъекта персональных данных, не дольше, чем этого требуют цели обработки персональных данных, если срок хранения персональных данных не установлен федеральным законом, договором, стороной которого, выгодоприобретателем или поручителем по которому является субъект персональных данных.
- Условием прекращения обработки персональных данных может являться достижение целей обработки персональных данных, истечение срока действия согласия субъекта персональных данных, отзыв согласия субъектом персональных данных или требование о прекращении обработки персональных данных, а также выявление неправомерной обработки персональных данных.
-
Перечень действий, производимых Оператором с полученными персональными данными
- Оператор осуществляет сбор, запись, систематизацию, накопление, хранение, уточнение (обновление, изменение), извлечение, использование, передачу (распространение, предоставление, доступ), обезличивание, блокирование, удаление и уничтожение персональных данных.
- Оператор осуществляет автоматизированную обработку персональных данных с получением и/или передачей полученной информации по информационно-телекоммуникационным сетям или без таковой.
-
Трансграничная передача персональных данных
- Оператор до начала осуществления деятельности по трансграничной передаче персональных данных обязан уведомить уполномоченный орган по защите прав субъектов персональных данных о своем намерении осуществлять трансграничную передачу персональных данных (такое уведомление направляется отдельно от уведомления о намерении осуществлять обработку персональных данных).
- Оператор до подачи вышеуказанного уведомления обязан получить от органов власти иностранного государства, иностранных физических лиц, иностранных юридических лиц, которым планируется трансграничная передача персональных данных, соответствующие сведения.
-
Конфиденциальность персональных данных
Оператор и иные лица, получившие доступ к персональным данным, обязаны не раскрывать третьим лицам и не распространять персональные данные без согласия субъекта персональных данных, если иное не предусмотрено федеральным законом.
-
Заключительные положения
- Пользователь может получить любые разъяснения по интересующим вопросам, касающимся
обработки его персональных данных, обратившись к Оператору с помощью электронной почты
mail@vhsframework.ru. - В данном документе будут отражены любые изменения политики обработки персональных данных Оператором. Политика действует бессрочно до замены ее новой версией.
- Актуальная версия Политики в свободном доступе расположена в сети Интернет по адресу https://vhsframework.ru/privacy/.
- Пользователь может получить любые разъяснения по интересующим вопросам, касающимся
обработки его персональных данных, обратившись к Оператору с помощью электронной почты
404
Страница не найдена