Why isn't an custom implemented VaadinServiceInitListener is listening in vaadin 13.0.2? - vaadin

I would like to validate user is signed in or not to achieve it i found something called VaadinServiceInitListener in vaadin 13.0.2 This class is used to listen to BeforeEnter event of all UIs in order to check whether a user is signed in or not before allowing entering any page.
I have created an vaadin 13.0.2 project with app-layout-addon by appreciated implemented login functionality and VaadinServiceInitListener to check whether a user is signed in or not.
public class AAACATInitListener implements VaadinServiceInitListener {
private static final long serialVersionUID = 1L;
private static InAppSessionContextImpl appContextImpl;
#Override
public void serviceInit(ServiceInitEvent event) {
System.out.println("in service init event");
event.getSource().addUIInitListener(new UIInitListener() {
private static final long serialVersionUID = 1L;
#Override
public void uiInit(UIInitEvent event) {
event.getUI().addBeforeEnterListener(new BeforeEnterListener() {
private static final long serialVersionUID = 1L;
#Override
public void beforeEnter(BeforeEnterEvent event) {
appContextImpl = (InAppSessionContextImpl)VaadinSession.getCurrent().getAttribute("context");
if (appContextImpl == null) {
WebBrowser webBrowser = UI.getCurrent().getSession().getBrowser();
String address = webBrowser.getAddress();
if(RememberAuthService.isAuthenticated(address) != null && !RememberAuthService.isAuthenticated(address).isEmpty()) {
//System.out.println("Found Remembered User....");
IBLSessionContext iblSessionContext = null;
try {
iblSessionContext = new UserBLManager().doRememberedStaffUserLogin(RememberAuthService.isAuthenticated(address), "");
if(iblSessionContext != null) {
InAppSessionContextImpl localAppContextImpl = new InAppSessionContextImpl();
localAppContextImpl.setBLSessionContext(iblSessionContext);
localAppContextImpl.setModuleGroupList(iblSessionContext.getSessionAccessControl().getPermittedModuleGroups());
appContextImpl = localAppContextImpl;
event.rerouteTo(ApplicationMainView.class);
}else {
Notification.show("Your access has been expired, Please contact your administrator", 5000, Position.BOTTOM_CENTER);
}
} catch (AuthenticationFailedException e) {
Notification.show("Authentication Failed, Please Reset Cookies And Try Again", 5000, Position.BOTTOM_CENTER);
} catch (Exception e){
e.printStackTrace();
Notification.show("Unexpected Error Occurred, Please Reset Cookies And Try Again", 5000, Position.BOTTOM_CENTER);
}
}else {
System.out.println("Session context is null, creating new context");
appContextImpl = new InAppSessionContextImpl();
VaadinSession.getCurrent().setAttribute("context", appContextImpl);
event.rerouteTo(LoginView.class);
}
} else {
System.out.println("Session context is not null");
InAppSessionContextImpl localAppContextImpl = new InAppSessionContextImpl();
localAppContextImpl.setBLSessionContext(appContextImpl.getBLSessionContext());
localAppContextImpl.setModuleGroupList(appContextImpl.getModuleGroupList());
appContextImpl = localAppContextImpl;
event.rerouteTo(ApplicationMainView.class);
}
}
});
}
});
}
public static void setBLSessionContext(IBLSessionContext iblSessionContext) {
appContextImpl.setBLSessionContext(iblSessionContext);
}
public static void setModuleGroupList(List<ModuleGroupVO> moduleGroupList) {
appContextImpl.setModuleGroupList(moduleGroupList);
}
private class InAppSessionContextImpl implements InAppSessionContext {
private static final long serialVersionUID = 1L;
private List<ModuleGroupVO> moduleGroupList;
private IBLSessionContext iblSessionContext;
private Map<String, Object> attributeMap;
public InAppSessionContextImpl() {
this.attributeMap = new HashMap<String, Object>();
}
#Override
public List<ModuleGroupVO> getModuleGroupList() {
return moduleGroupList;
}
public void setModuleGroupList(List<ModuleGroupVO> moduleGroupList) {
this.moduleGroupList = moduleGroupList;
}
#Override
public IBLSessionContext getBLSessionContext() {
return iblSessionContext;
}
public void setBLSessionContext(IBLSessionContext iblSessionContext) {
this.iblSessionContext = iblSessionContext;
}
#Override
public IBLSession getBLSession() {
if(iblSessionContext != null)
return iblSessionContext.getBLSession();
return null;
}
#Override
public boolean isPermittedAction(String actionAlias) {
if (getBLSessionContext() != null) {
if (getBLSessionContext().getSessionAccessControl() != null) {
return getBLSessionContext().getSessionAccessControl().isPermittedAction(actionAlias);
}
}
return false;
}
#Override
public void setAttribute(String key, Object attribute) {
attributeMap.put(key, attribute);
}
#Override
public Object getAttribute(String key) {
return attributeMap.get(key);
}
}
}
Expected results redirect to login page if user not signed in or else to main application page but AAACATInitListener is not listening.

If you are using Spring, simply add a #Component annotation to the class and it should work. If youre not using Spring, follow #codinghaus' answer.

To make Vaadin recognize the VaadinServiceInitListener you have to create a file called com.vaadin.flow.server.VaadinServiceInitListener and put it under src/main/resources/META-INF/services. Its content should be the full path to the class that implements the VaadinServiceInitListener interface. Did you do that?
You can also find a description on that in the tutorial.

The correct pattern to use beforeEnter(..) is not do it via VaadinServiceInitListener , instead you should implement BeforeEnterObserver interface in the view where you need use it and override beforeEnter(..) method with your implementation.
public class MainView extends VerticalLayout implements RouterLayout, BeforeEnterObserver {
...
#Override
public void beforeEnter(BeforeEnterEvent event) {
...
}
}

Related

keycloak backchannel logout spring session that use redis as session store

I use keycloak as a Central Authentication Service for (single sign on/out) feature.
I have app1, app2, app3. app1 and app2 is monothetic application. app3 use spring session (use redis as session store),
All feature work fine. But I use the back channel to logout for SSO(single sign out) feature, that's works for app1 and app2. But it not work for this app3.
I wonder how to back channel logout application that use spring session
The keycloak admin url invoke when client user send a logout request to it.I find that KeycloakAutoConfiguration#getKeycloakContainerCustomizer() inject WebServerFactoryCustomizer for add KeycloakAuthenticatorValve, and that Valve
use CatalinaUserSessionManagement, but it have not any info about redis as its session store. So I add a customizer for enhence the Valve.
first i set the order of the autoconfig, because extra customizer must be callback after it.
#Slf4j
#Component
public class BeanFactoryOrderWrapper implements DestructionAwareBeanPostProcessor {
#Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
}
#Override
public boolean requiresDestruction(Object bean) {
return true;
}
#Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("getKeycloakContainerCustomizer")) {
Object wrapRes = this.wrapOrder(bean);
return wrapRes;
}
return bean;
}
#Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
private Object wrapOrder(Object bean) {
log.info("rewrite keycloak auto config customizer Order for next custom");
final WebServerFactoryCustomizer origin = (WebServerFactoryCustomizer) bean;
return new KeycloakContainerCustomizerWithOrder(origin);
}
}
class KeycloakContainerCustomizerWithOrder implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered {
private final WebServerFactoryCustomizer origin;
public KeycloakContainerCustomizerWithOrder(WebServerFactoryCustomizer origin) {
this.origin = origin;
}
#Override
public void customize(ConfigurableServletWebServerFactory factory) {
origin.customize(factory);
}
#Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE - 1;
}
}
I extra RedisIndexedSessionRepository, and set it to proxy object
#Slf4j
#Configuration
#RequiredArgsConstructor
class ContainerConfig {
private final RedisIndexedSessionRepository sessionRepository;
#Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> getKeycloakContainerCustomizerGai() {
return configurableServletWebServerFactory -> {
if (configurableServletWebServerFactory instanceof TomcatServletWebServerFactory) {
TomcatServletWebServerFactory container = (TomcatServletWebServerFactory) configurableServletWebServerFactory;
container.getContextValves().stream().filter(ele -> ele.getClass() == KeycloakAuthenticatorValve.class).findFirst().map(ele -> (AbstractKeycloakAuthenticatorValve) ele).ifPresent(valve -> {
try {
final Field field = AbstractKeycloakAuthenticatorValve.class.getDeclaredField("userSessionManagement");
field.setAccessible(true);
final CatalinaUserSessionManagement origin = (CatalinaUserSessionManagement) field.get(valve);
field.set(valve, new CatalinaUserSessionManagementGai(origin, sessionRepository));
} catch (Exception e) {
log.error("enhence valve fail");
}
});
}
};
}
}
#Slf4j
class CatalinaUserSessionManagementGai extends CatalinaUserSessionManagement {
private final CatalinaUserSessionManagement origin;
private final RedisIndexedSessionRepository sessionRepository;
public CatalinaUserSessionManagementGai(CatalinaUserSessionManagement origin, RedisIndexedSessionRepository sessionRepository) {
this.origin = origin;
this.sessionRepository = sessionRepository;
}
public void login(Session session) {
origin.login(session);
}
public void logoutAll(Manager sessionManager) {
origin.logoutAll(sessionManager);
}
public void logoutHttpSessions(Manager sessionManager, List<String> sessionIds) {
for (String sessionId : sessionIds) {
logoutSession(sessionManager, sessionId);
}
}
protected void logoutSession(Manager manager, String httpSessionId) {
try {
final Method method = CatalinaUserSessionManagement.class.getDeclaredMethod("logoutSession", Manager.class, String.class);
method.setAccessible(true);
method.invoke(origin,manager,httpSessionId);
} catch (Exception e) {
log.error("session manager proxy invoke error");
}
// enhence part
sessionRepository.deleteById(httpSessionId);
}
protected void logoutSession(Session session) {
try {
final Method method = CatalinaUserSessionManagement.class.getDeclaredMethod("logoutSession", Session.class);
method.setAccessible(true);
method.invoke(origin,session);
} catch (Exception e) {
log.error("session manager proxy invoke error");
}
}
public void sessionEvent(SessionEvent event) {
origin.sessionEvent(event);
}
}
that work for me

NestedSlot presenter with own url- how to setup url for NestedSlot presenters

I have parent presenter: UsersListPresenter that contains nested presenter: UserPresenter in NestedSlot.
public class UsersListPresenter extends ApplicationPresenter<UsersListPresenter.MyView, UsersListPresenter.MyProxy> implements UsersListUiHandlers,
OpenWindowEvent.OpenModaHandler, UserAddedEvent.UserAddedHandler {
#ProxyStandard
#NameToken(ClientRouting.Url.users)
#UseGatekeeper(IsUserLoggedGatekeeper.class)
public interface MyProxy extends TabContentProxyPlace<UsersListPresenter> {}
#TabInfo(container = AppPresenter.class)
static TabData getTabLabel(IsUserLoggedGatekeeper adminGatekeeper) {
return new MenuEntryGatekeeper(ClientRouting.Label.users, 1, adminGatekeeper);
}
public interface MyView extends View, HasUiHandlers<UsersListUiHandlers> {
void setUsers(List<UserDto> users);
void addUser(UserDto user);
}
public static final NestedSlot SLOT_USER_WINDOW = new NestedSlot();
//interface Driver extends SimpleBeanEditorDriver<UserDto, UserEditor> {}
private static final UserService userService = GWT.create(UserService.class);
private AppPresenter appPresenter;
private UserTestPresenter userPresenter;
#Inject
UsersListPresenter(EventBus eventBus, MyView view, MyProxy proxy, AppPresenter appPresenter, UserTestPresenter userPresenter) {
super(eventBus, view, proxy, appPresenter, AppPresenter.SLOT_TAB_CONTENT);
this.appPresenter = appPresenter;
this.userPresenter = userPresenter;
getView().setUiHandlers(this);
}
#Override
protected void onBind() {
super.onBind();
updateList();
setInSlot(SLOT_USER_WINDOW, userPresenter);
addRegisteredHandler(OpenWindowEvent.getType(), this);
}
#Override
protected void onReveal() {
super.onReveal();
initializeApplicationUiComponents(ClientRouting.Label.users);
}
#Override
public void onOpenModal(OpenWindowEvent event) {
openModal(event.getUser());
}
#Override
public void openModal(UserDto user) {
userPresenter.openModal(user);
}
}
public class UsersListView extends ViewWithUiHandlers<UsersListUiHandlers> implements UsersListPresenter.MyView {
interface Binder extends UiBinder<Widget, UsersListView> {}
#UiField
SimplePanel windowSlot;
#Inject
UsersListView(Binder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
}
#Override
public void setInSlot(Object slot, IsWidget content) {
if (slot == UsersListPresenter.SLOT_USER_WINDOW) {
windowSlot.setWidget(content);
}
};
}
public class UserTestPresenter extends Presenter<UserTestPresenter.MyView, UserTestPresenter.MyProxy> implements UserTestUiHandlers {
public interface MyView extends View, HasUiHandlers<UserTestUiHandlers> {
void openModal(UserDto user);
}
#ProxyStandard
#NameToken("/user/{userid}")
public interface MyProxy extends ProxyPlace<UserTestPresenter> {
}
private PlaceManager placeManager;
#Inject
public UserTestPresenter(EventBus eventBus, MyView view, MyProxy proxy, PlaceManager placeManager) {
super(eventBus, view, proxy, UsersListPresenter.SLOT_USER_WINDOW);
this.placeManager = placeManager;
getView().setUiHandlers(this);
}
#Override
public void prepareFromRequest(PlaceRequest request) {
GWT.log("Prepare from request " + request.getNameToken());
}
#Override
protected void onReveal() {
super.onReveal();
};
public void openModal(UserDto user) {
getView().openModal(user);
}
#Override
public void onSave(UserDto user) {
// TODO Auto-generated method stub
MaterialToast.fireToast("onSaveClick in new presenter for " + user.toString());
}
#Override
public void onClose() {
PlaceRequest placeRequest = new PlaceRequest.Builder().nameToken("/users/{userid}").with("userid", "list").build();
placeManager.revealPlace(placeRequest);
}
public class UserTestView extends ViewWithUiHandlers<UserTestUiHandlers> implements UserTestPresenter.MyView {
interface Binder extends UiBinder<Widget, UserTestView> {}
#UiField
MaterialRow main;
#UiField
MaterialWindow window;
#UiField
MaterialLabel userName, userFullName;
#UiField
MaterialButton saveButton;
private HandlerRegistration saveButtonClickHandler;
#Inject
UserTestView(Binder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
// adding default click handler
saveButtonClickHandler = saveButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {}
});
}
#Override
public void openModal(final UserDto user) {
userName.setText(user.getEmail());
userFullName.setText(user.getId() + " " + user.getEmail());
saveButtonClickHandler.removeHandler();
saveButtonClickHandler = saveButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
getUiHandlers().save(user);
}
});
window.openWindow();
}
}
when user from list is clicked the window with clicked users is opened. At this moment url should change from http://localhost:8080/cms/#/users/list to http://localhost:8080/cms/#/user/3
for better understanding below is screencast from that code:
and now some job done, but still not ideal:
here is my gwtp configuration:
public class ClientModule extends AbstractPresenterModule {
#Override
protected void configure() {
bind(RestyGwtConfig.class).asEagerSingleton();
install(new Builder()//
.defaultPlace(ClientRouting.HOME.url)//
.errorPlace(ClientRouting.ERROR.url)//
.unauthorizedPlace(ClientRouting.LOGIN.url)//
.tokenFormatter(RouteTokenFormatter.class).build());
install(new AppModule());
install(new GinFactoryModuleBuilder().build(AssistedInjectionFactory.class));
bind(CurrentUser.class).in(Singleton.class);
bind(IsAdminGatekeeper.class).in(Singleton.class);
bind(IsUserLoggedGatekeeper.class).in(Singleton.class);
bind(ResourceLoader.class).asEagerSingleton();
}
}
As You can see I use tokenFormatter(RouteTokenFormatter.class)
how it can be achieved with gwtp framework?
One way to achieve this is to change the URL of your UserListPresenter to support passing in the user id as an optional parameter:
#NameToken("/users/{userid}")
public interface MyProxy extends ProxyPlace<UserListPresenter> {
}
You need to override the prepareFromRequest method of your UserListPresenter and there you check if the userid is set and open your modal window if it is.
#Override
public void prepareFromRequest(PlaceRequest request) {
String userid = request.getParameter("userid", "list");
if (userid != "list") {
# open modal
}
else {
# close modal
}
}
You also need to change the logic when you click your on a user in your list:
#Override
public void onOpenModal(OpenWindowEvent event) {
PlaceRequest placeRequest = new PlaceRequest.Builder()
.nameToken("/users/{userid}")
.with("userid", event.getUser().getId())
.build();
placeManager.revealPlace(placeRequest);
}
This will change the URL and open the modal.

Stateless EJB not injected in message driven bean (MDB)

I have a message driven bean (MDB) that implements MessageListener and has several EJB attributes but non of them are injected so I have to inject them manually. The MDB also has a resource and a CDI bean that are injected fine.
Why the EJBs are not injected automatically? I use NotificationService EJB at other parts of the application and they are injected. Any clue about how to figure out the problem?
I don't get any error from Weblogic 12.1.3, so I can't figure out what's happening here. My code is (full of traces for debugging purposes). I've removed javadocs and method implementations that are not relevant to the problem:
#MessageDriven(name = "MailMessageConsumer", description = "JMS consumer", mappedName = MailJndiConfiguration.JNDI_QUEUE,
activationConfig = {
#ActivationConfigProperty(propertyName = "acknowledgeMode",
propertyValue = "Auto-acknowledge"),
#ActivationConfigProperty(propertyName = "destinationType",
propertyValue = "javax.jms.Queue")
})
#TransactionAttribute(TransactionAttributeType.REQUIRED)
#MessageReceiver(responsibility = "Consumes JMS messages of type MailMessage")
public class MailMessageConsumer implements MessageListener {
private static final Logger log = LoggerFactory.getLogger(MailMessageConsumer.class);
#Resource
private MessageDrivenContext messageDrivenContext;
#EJB
private NotificationService notificationService;
#EJB
private MailClient mailClient;
#Inject
private ApplicationInformation applicationInformation;
#Override
public void onMessage(Message message) {
if (mailClient == null) {
log.error("mailClient object is null");
try {
log.info("Instantiating MailClient manually...");
mailClient = BeanManagerHelper.getReference(MailClient.class);
} catch (Exception e) {
log.error("Cannot instantiate MailClient manually", e);
}
}
if (notificationService == null) {
log.error("notificationService object is null");
try {
log.info("Instantiating NotificationService manually...");
notificationService = BeanManagerHelper.getReference(NotificationService.class);
} catch (Exception e) {
log.error("Cannot instantiate NotificationService manually", e);
}
}
// This never happens
if (applicationInformation == null) {
log.error("applicationInformation object is null");
}
// This never happens
if (messageDrivenContext == null) {
log.error("messageDrivenContext object is null");
}
deliverMessage(message);
}
private void deliverMessage(Message message) {
// Not important
}
private MailMessage retrieveMessage(Message message) {
// Not important
}
private void sendEmail(MailMessage mailMessage) {
// Not important
}
}
MailClient EJB:
#Stateless
#LocalBean
#TransactionAttribute(TransactionAttributeType.MANDATORY)
#Service
public class MailClient {
private static final Logger logger = LoggerFactory.getLogger(MailClient.class);
#Resource(mappedName = MailJndiConfiguration.JNDI_MAIL_SESSION)
private Session mailSession;
#EJB
private NotificationService notificationService;
#Inject
private ApplicationInformation applicationInformation;
enum ValidationError {
NULL_OBJECT("Mail message is null"),
CONTENT_TYPE_EMPTY("Content type not initialized"),
BODY_EMPTY("Message body content is empty");
private static final String ERROR_MESSAGE_PREFIX = "Invalid mail message: ";
private String message = ERROR_MESSAGE_PREFIX;
ValidationError(String message) {
this.message += message;
}
public String getMessage() {
return message;
}
}
public void sendMail(MailMessage mailMessage) throws MailMessageSendingException {
// Not important
}
}
NotificationService EJB:
#Stateless
#LocalBean
#TransactionAttribute(TransactionAttributeType.MANDATORY)
#Service
public class NotificationService {
private static final Logger logger = LoggerFactory.getLogger(NotificationService.class);
#PersistenceContext(unitName = "myEntityManager")
private EntityManager entityManager;
#EJB
private NotificationPendingMessageValidator notificationPendingMessageValidator;
#EJB
private NotificationFinder notificationFinder;
#Inject
private ApplicationInformation applicationInformation;
public NotificationPendingMessageEntity saveNotificationMessageForDeferredMail(NotificationPendingMessageEntity notificationPendingMessageEntity) throws ValidationException {
// Not important
}
public List<NotificationPendingMessageEntity> findNotificationPendingMessageEntities(TimeSlot timeSlot) {
// Not important
}
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public NotificationMailEntity createNewMailEntity() {
// Not important
}
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void updateMailEntity(NotificationMailEntity mailEntity) {
// Not important
}
public void createNotificationMessageProcessedEntity(NotificationProcessedMessageEntity notificationProcessedMessageEntity) {
// Not important
}
public void removeNotificationMessagePendingEntity(NotificationPendingMessageEntity notificationPendingMessageEntity) {
// Not important
}
public void reportMailFailure(NotificationMailEntity mailEntity, String failureNotice) {
// Not important
}
}
Using #Inject for injecting the EJBs instead of #EJB annotation works fine. So there should be a problem with some Weblogic's patches, because testing it in another Weblogic (same version, different patches) it worked as well

How to change the main view of a Vaadin 7 application?

I want to write a Vaadin 7 application (see MyVaadinUI below), which asks the user to enter user name and password.
If they are correct, another view (see MainUI below) should appear and take the entire area (replace the login view).
I tried to implement this transition in the method MyVaadinUI.goToMainWindow, but I get the error
java.lang.RuntimeException: Component must be attached to a session when getConnectorId() is called for the first time
at com.vaadin.server.AbstractClientConnector.getConnectorId(AbstractClientConnector.java:417)
at com.vaadin.server.communication.ConnectorHierarchyWriter.write(ConnectorHierarchyWriter.java:67)
at com.vaadin.server.communication.UidlWriter.write(UidlWriter.java:143)
at com.vaadin.server.communication.UidlRequestHandler.writeUidl(UidlRequestHandler.java:149)
at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:97)
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:37)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1371)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:238)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
when I run the application and press the button.
How can I fix it?
#Theme("mytheme")
#SuppressWarnings("serial")
public class MyVaadinUI extends UI
{
private TextField userNameTextField;
private PasswordField passwordTextField;
#WebServlet(value = "/*", asyncSupported = true)
#VaadinServletConfiguration(productionMode = false, ui = MyVaadinUI.class, widgetset = "ru.mycompany.vaadin.demo.AppWidgetSet")
public static class Servlet extends VaadinServlet {
}
#Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
addUserNameTextField(layout);
addPasswordTextField(layout);
addButton(layout, request);
}
private void addPasswordTextField(Layout aLayout) {
passwordTextField = new PasswordField("Пароль:");
aLayout.addComponent(passwordTextField);
}
private void addUserNameTextField(final Layout aLayout) {
userNameTextField = new TextField("Пользователь:");
aLayout.addComponent(userNameTextField);
}
private void addButton(final Layout aParent, final VaadinRequest request) {
final Button button = new Button("Войти");
button.addClickListener(new Button.ClickListener() {
public void buttonClick(Button.ClickEvent event) {
final boolean credentialsCorrect = checkCredentials();
if (credentialsCorrect) {
goToMainWindow(request);
} else {
[...]
}
}
});
aParent.addComponent(button);
}
private void goToMainWindow(final VaadinRequest aRequest) {
final MainUI mainUI = new MainUI();
mainUI.init(aRequest);
setContent(mainUI);
}
}
#Theme("mytheme")
#SuppressWarnings("serial")
public class MainUI extends UI {
#Override
protected void init(final VaadinRequest vaadinRequest) {
final HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
setContent(splitPanel);
splitPanel.setSizeFull();
splitPanel.setSplitPosition(200, Unit.PIXELS);
final String[] tabLabels = new String[] {
"Tree item 1",
"Tree item 2"};
final Tree tree = new Tree();
for (int i=0; i < tabLabels.length; i++)
{
addTreeItem(tree, tabLabels[i]);
}
splitPanel.setFirstComponent(tree);
splitPanel.setSecondComponent(new Label("Test"));
}
private void addTreeItem(final Tree aTree, final String aLabel) {
aTree.addItem(aLabel);
}
}
On the Vaadin forum someone suggested to use the navigator, which solved my problem.
I'd rather think that MainUI should extend HorizontalSplitPanel, not UI. It is strange concept to me to insert one UI into another.
You can use #SpringUI for the main class which extends UI:
#SpringUI
#Theme("mytheme")
#Widgetset("com.MyAppWidgetset")
#PreserveOnRefresh
public class MainUI extends UI {
private static final long serialVersionUID = -8247521108438815011L;
private static Locale locale = VaadinSession.getCurrent().getLocale();
#Autowired
private ToolBoxMessageSource messageSource;
#Autowired
private SpringViewProvider springViewProvider;
public MainUI() {
}
//Initializes navigator with SpringViewProvider and add all existing
//and ui specific assigned views to navigator.
#Override
protected void init(VaadinRequest vaadinRequest) {
Navigator navigator = new Navigator(this, this);
// Adding springViewProvider for spring autowiring
navigator.addProvider(springViewProvider);
// Adding all views for navigation
navigator.addView(LoginView.NAME, LoginView.class);
navigator.addView(MainView.NAME, MainView.class);
navigator.addView(MailToolView.NAME, MailToolView.class);
navigator.addView(AdminView.NAME, AdminView.class);
navigator.addView(EditRecipientView.NAME, EditRecipientView.class);
navigator.addView(EditRecipientsView.NAME, EditRecipientsView.class);
navigator.addView(ServerView.NAME, ServerView.class);
navigator.addView(TestJobView.NAME, TestJobView.class);
navigator.addView("", new LoginView());
navigator.navigateTo(LoginView.NAME);
navigator.setErrorView(LoginView.class);
// security: if user changes view check if the user has the required rights
navigator.addViewChangeListener(new ViewChangeListener() {
private static final long serialVersionUID = 7330051193056583546L;
#Override
public boolean beforeViewChange(ViewChangeEvent event) {
Toolbox toolbox = getSession().getAttribute(Toolbox.class);
if (TbRightManagement.checkAccess(event.getNewView().getClass(), toolbox)) {
return true;
} else {
if (toolbox != null) {
TBNotification.show(messageSource.getMessage("access.denied.title", locale),
messageSource.getMessage("access.denied.no_permissions.msg", locale),
Type.ERROR_MESSAGE);
navigator.navigateTo(MainView.NAME);
return false;
} else {
TBNotification.show(messageSource.getMessage("access.denied.title", locale),
messageSource.getMessage("access.denied.not_loggedin.msg", locale),
Type.ERROR_MESSAGE);
navigator.navigateTo(LoginView.NAME);
return false;
}
}
}
#Override
public void afterViewChange(ViewChangeEvent event) {}
});
}
}
And for the other views, as an example EditRecipientsView should be a #SpringView which extends a Vaadin Designer and implements a Vaadin View.
#SpringView(name = EditRecipientsView.NAME)
#Theme("mytheme")
#TbRight(loggedIn = true, mailTool = true)
public class EditRecipientsView extends RecipientsDesign implements View {
private static final long serialVersionUID = 1L;
public static final String NAME = "editRecipients";
private static Locale locale = VaadinSession.getCurrent().getLocale();
private BeanItemContainer<Recipient> recipientContainer;
private Uploader uploader;
#Autowired
private ToolBoxMessageSource messageSource;
public EditRecipientsView() {
super();
}
//Initializes the ui components of the recipient view.
#PostConstruct
public void init() {
btn_addRecipient.addClickListener(e -> { MainUI.getCurrent().getNavigator().navigateTo(EditRecipientView.NAME);});
}
//Handling data when entering this view.
#Override
public void enter(ViewChangeEvent event) {
if (getSession().getAttribute(UIMailing.class) != null) {
List<Recipient> recipientList = getSession().getAttribute(UIMailing.class).getRecipients();
if (recipientList != null) {
recipientContainer.removeAllItems();
} else {
recipientList = new ArrayList<Recipient>();
}
recipientContainer.addAll(recipientList);
recipient_table.sort(new Object[] {"foreName", "lastName"}, new boolean[] {true, true});
}
}
}

How Can i show urls clicked by user in Primefaces+JSF2

I am using JSF2 with Prime faces. I will want to show all the previous links or Urls clicked by user in every page.How can i do this?
Here's a good link for you: How can I get the request URL from a Java Filter?
What I would do is use something like that example and do a set of three URLs.
//Using linked example
public class MyFilter implements Filter {
public void init(FilterConfig config) throws ServletException { }
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
chain.doFilter(request, response);
String url = ((HttpServletRequest) request).getPathTranslated();
UrlBean urlBean = (UrlBean) FacesContext.getCurrentInstance()getApplication().getValueBinding("#{urlBean}");
urlBean.storeUrl(url);
}
public void destroy() { }
}
This is totally untested, but the idea should work. You would just need to implement some logic (probably a stack) for your component so it stores what you need. (Obviously you might end up at the same URL multiple times). I should note the UrlBean is just an abstract idea, you would have to implement it
Hi I have created this Singleton class to put the Url Browsed by a User.
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class UrlHistory {
#SuppressWarnings("rawtypes")
private static Map<String, List> store = new HashMap<String, List>();
private static UrlHistoryBean instance = null;
public static UrlHistoryBean getInstance() {
if (instance == null) {
instance = new UrlHistoryBean();
}
return instance;
}
LinkedList<UrlData> urlList = new LinkedList<UrlHistoryBean.UrlData>();
public void addUrl(String sessionId, String urlString, int urlId) {
UrlData data = new UrlData();
data.setUrlName(urlString);
data.setUrlId(companyId);
if (urlList.isEmpty()) {
urlList.add(data);
} else {
boolean isEqual = false;
for (UrlData urlDataObj : urlList) {
if (urlDataObj.equals(data))
isEqual = true;
}
if(!isEqual)
urlList.addFirst(data);
}
store.put(sessionId, urlList);
}
#SuppressWarnings("rawtypes")
public static Map<String, List> getStore() {
return store;
}
#SuppressWarnings("rawtypes")
public static void setStore(Map<String, List> store) {
UrlHistoryBean.store = store;
}
public class UrlData {
String urlName;
int urlId;
public String getUrlName() {
return UrlName;
}
public void setUrlName(String UrlName) {
this.UrlName = UrlName;
}
public int getUrlId() {
return urlId;
}
public void setUrlId(int urlId) {
this.urlId = urlId;
}
public boolean equals(UrlData rData) {
boolean bEqual = false;
if (this.getUrlId() > 0 && rData.getUrlId() > 0 && this.getUrlId() == rData.getUrlId()) {
bEqual = true;
}
return bEqual;
}
}
}

Resources