Strange, my reply on friday didn't make it to the mailing-list, so here once
again:
Thanks to Thorsten Schöning & subes for their feedback, even though none of the
suggestions worked for my case. But it
helped somehow to think about it from a different perspective. I was thinking
way too complicated. (My solution is at
the end fo the mail).
@Thorsten:
The user is not the only criteria deciding the visibility. We have several
links and a lot of them have additional
criteria depending on the state of the application. I am also aware of the
discussion setVisible vs. isVisible. But on
our project we decided to use isVisible as long as there is no significant
performance penalty.
Beside that after fixing the problem with the links, I could reproduce the
problematic behaviour with other pages which
relied on the user-object.
@subes:
I tried also to call invalidate() in my signOut()-method which resulted in a
stackoverflow since invalidate() calls
itself signout() which resulted in an endless loop.
And replaceSession() was also not helpful since Wicket tried to load the last
page from the page store and render the
components which needed the user-object which was not there anymore.
How I fixed it:
In MySession I just check if the user is null and throw an PageExpiredException
if it is.
public User getUser() {
if (user == null) {
throw new PageExpiredException("No user available. Page seems to be
expired.");
}
return user;
}
This way I'm always getting to the log-in page if the user-object does not
exists. My initial thought was, to empty the
page store so that Wicket tries to create a new instance of the page and the
AuthorizeInstantiation annotation would
have redirected to the login-page. Do not ask me why I was thinking so
complicated in the beginning.
Have a nice weekend.
On 04/14/2016 03:35 PM, Joachim Rohde wrote:
> Hello,
>
> short version of my question: how do I evict the page store to force Wicket
> to create a new instance after using the
> back-button?
>
> Longer version:
>
> A user is redirected after login to my main page. On my main page I have
> several links in onInitialize() which
> overwrites isVisible checking the role of the logged-in user, like this:
>
> @AuthorizeInstantiation({MyRole.sAdmin})
> public abstract class AbstractSecureBasePage extends AbstractBasePage
> implements ModelDetacher {
> [...]
> add(new Link("managementLink") {
> @Override
> public void onClick() {
> setResponsePage(Management.class);
> }
>
> @Override
> public boolean isVisible() {
> return MySession.get().getUser().hasRole(MyRole.ADMIN);
> }
> });
> [...]
> }
>
> My session:
>
> public class MySession extends AuthenticatedWebSession {
> [...]
> @Override
> public void signOut() {
>
> user = null;
>
> final RequestCycle requestCycle = RequestCycle.get();
>
> if (RequestCycle.get() != null && requestCycle.getRequest() != null
> &&
> ServletWebRequest.class.isAssignableFrom(RequestCycle.get().getRequest().getClass()))
> {
> LOGGER.log(Level.FINE, "Invalidating HttpSession-object {0}",
> ((ServletWebRequest)
> RequestCycle.get().getRequest()).getContainerRequest().getSession().getId());
> ((ServletWebRequest)
> RequestCycle.get().getRequest()).getContainerRequest().getSession().invalidate();
> }
> super.signOut();
> }
> }
>
> After the log-out the user is redirected back to the login-page. If the user
> now click the browsers back button Wicket
> tries to fetch the last page from the page store and checks the links
> visibility which will result in a
> NullPointerException due to the fact that getUser() returns null.
>
> I attempted several solutions:
>
> 1) Checking in every isVisible() if the user is null. This *does* work but I
> have quite a lot of links and I would like
> to go with this solution only if I cannot find any other.
>
> 2) Checking at the very beginning of onInitialize() if the user is null. This
> does not work since the components are
> coming from the page store and onInitialize() is not called.
>
> 3) Overwriting onBeforeRender() of the main page. This does not work since
> it's only called if a component is visible.
>
> 4) My next idea was, to empty the page store within my signOut-method.
> I tried several things:
> getApplication().getSessionStore().destroy();
> getPageManager().clear();
> getPageManager().destroy();
> getPageManager().commitRequest();
> None of them worked.
>
> getPageManager().destroy(); provokes even a NullPointerException within
> Wicket itself (after using the back-button):
>
> java.lang.NullPointerException
> at
> org.apache.wicket.page.PageStoreManager$SessionEntry.getPage(PageStoreManager.java:203)
> at
> org.apache.wicket.page.PageStoreManager$PersistentRequestAdapter.getPage(PageStoreManager.java:357)
> at
> org.apache.wicket.page.AbstractPageManager.getPage(AbstractPageManager.java:82)
> at
> org.apache.wicket.page.PageManagerDecorator.getPage(PageManagerDecorator.java:50)
> at
> org.apache.wicket.page.PageAccessSynchronizer$2.getPage(PageAccessSynchronizer.java:246)
> at
> org.apache.wicket.DefaultMapperContext.getPageInstance(DefaultMapperContext.java:113)
> at
> org.apache.wicket.core.request.handler.PageProvider.getStoredPage(PageProvider.java:299)
> at
> org.apache.wicket.core.request.handler.PageProvider.isNewPageInstance(PageProvider.java:211)
> at
> org.apache.wicket.core.request.mapper.AbstractBookmarkableMapper.processHybrid(AbstractBookmarkableMapper.java:261)
> at
> org.apache.wicket.core.request.mapper.AbstractBookmarkableMapper.mapRequest(AbstractBookmarkableMapper.java:365)
> at
> org.apache.wicket.request.mapper.CompoundRequestMapper.mapRequest(CompoundRequestMapper.java:150)
> at
> org.apache.wicket.request.cycle.RequestCycle.resolveRequestHandler(RequestCycle.java:189)
> at
> org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:219)
> at
> org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:293)
> at
> org.apache.wicket.protocol.http.WicketFilter.processRequestCycle(WicketFilter.java:261)
> at
> org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:203)
> at
> org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:284)
> [...]
>
> Line 203 of the PageStoreManager looks like:
>
> // not found, ask pagestore for the page
> return getPageStore().getPage(sessionId, id);
>
> I am not sure if here should be a null-check on getPageStore (since I have no
> clue what should be returned if
> getPageStore() returns null).
>
> Long story short: is there a more elegant solution to my problem than the
> first solution that I've tried?
> I had the hope I could empty the page store and Wicket would be so smart to
> create a new instance of the page if the
> page store is empty (which would solve my problem since
> AuthorizeInstantiation would cause Wicket to redirect to the
> LoginPage again).
>
>
> Joachim
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
--
SOLVIT GmbH
Joachim Rohde
Softwareentwicklung
Lise-Meitner-Straße 4
24941 Flensburg
Telefon: +49 461 57 49 85 94
Fax: +49 461 57 49 88 99
Geschäftsführung:
Benjamin Klink,
Karsten Paulsen,
Helge Werlein
Amtsgericht Flensburg HRB 9450 FL
St.-Nr.: 15/296/14057 - USt-Id.: DE 283 368 011
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]