Routing API
This section describes the key concepts of the routing API.
Route Registration
To register a route for a screen, add the @Route
annotation to the screen controller, for example:
@Route("button-screen")
public class ButtonScreen extends Screen {
}
The annotation has three parameters:
-
path
(orvalue
) is the route itself; -
parentPrefix
is used for route squashing (see below). -
root
is the boolean property that enables to specify whether a route is registered for the root screen (like Login screen or Main screen). The default value isfalse
.
Creating a Root Screen for Anonymous User
If you create a root screen with a path other than the default login
and make it available by a link without login, you should enable it for the anonymous user. Otherwise, when users enter the URL like /#your-root-screen
, they will be re-directed to the /#login
link instead of opening your root screen.
-
Create your screen, for example,
MyAnonymousScreen
, with a button that opens the login screen:@UiController("MyAnonymousScreen") @UiDescriptor("my-anonymous-screen.xml") @Route(path = "anonymous") public class MyAnonymousScreen extends Screen { @Autowired private Screens screens; @Autowired private UiProperties uiProperties; @Subscribe("showLoginScreenBtn") protected void onShowLoginScreenBtnClick(Button.ClickEvent event) { String loginScreenId = uiProperties.getLoginScreenId(); Screen loginScreen = screens.create(loginScreenId, OpenMode.ROOT); loginScreen.show(); } }
-
Create the
AnonymousRole
and allow access toMyAnonymousScreen
:@ResourceRole(name = "AnonymousRole", code = AnonymousRole.CODE) public interface AnonymousRole { String CODE = "anonymous-role"; @ScreenPolicy(screenIds = {"MyAnonymousScreen"}) void screens(); }
-
Grant
AnonymousRole
to the anonymous user in theDatabaseUserRepository
:@Override protected void initAnonymousUser(User anonymousUser) { Collection<GrantedAuthority> authorities = getGrantedAuthoritiesBuilder() .addResourceRole(AnonymousRole.CODE) .build(); anonymousUser.setAuthorities(authorities); }
-
In the
application.properties
file enable anonymous access and specify which screen should be displayed for the anonymous user:# enable anonymous access jmix.ui.allow-anonymous-access=true # initial screen for anonymous user jmix.ui.initial-screen-id=MyAnonymousScreen
-
Launch the application and make sure that the screen you created opens at
/#anonymous
.
Route Squashing
This feature is designed to keep the URL clean and readable when opening multiple screens with routes having the same parts.
Suppose that we have browser and editor screens for the Customer
entity:
@Route("customers")
public class CustomerBrowse extends StandardLookup<Customer> {
}
@Route("customers/edit")
public class CustomerEdit extends StandardEditor<Customer> {
}
URL squashing is used to avoid repeating the customers
route in the URL when the editor screen is opened right after the browser. Just specify the repeated part in the parentPrefix
parameter of the @Route
annotation on the editor screen:
@Route(value = "customers/edit", parentPrefix = "customers")
public class CustomerEdit extends StandardEditor<Customer> {
}
When the editor is opened in the same tab as the browser, the resulting address will be like #main/0/customers/edit?id=…
UI State Mapping to URL
The UrlRouting
interface allows you to change the current application URL according to the current screen and some parameters. It has the following methods:
-
pushState()
- changes the address and pushes new browser history entry; -
replaceState()
- replaces the address without adding new browser history entry; -
getState()
- returns a current state as theNavigationState
object.
The pushState()/replaceState()
methods accept the current screen controller and optional map of parameters.
See an example of using UrlRouting
in the section below.
Navigation Filter
The navigation filter mechanism allows you to prevent transition to some routes.
A navigation filter is a Spring bean that implements the NavigationFilter
interface. The @Order
annotation can be used to configure the order of invocation of all navigation filters. The JmixOrder.HIGHEST_PRECEDENCE
and JmixOrder.LOWEST_PRECEDENCE
constants define the range which is used by filters defined in the framework.
The NavigationFilter
interface has the allowed()
method, which accepts two arguments: current navigation state fromState
and requested navigation state toState
. The method returns the AccessCheckResult
instance and checks whether the transition from the current navigation state to the requested navigation state is allowed.
See JmixLoginScreenFilter
as an example. It is designed for checking whether the current session is authenticated to prevent navigation to the login screen when the user is logged in already.