Myfaces CODI DefaultErrorView - examples anywhere? - jsf

I've seen a reference to a DefaultErrorView in Myfaces CODI but as usual the
documentation leaves everything to the imagination. I've really found CODI to be a
great JSF addon, but it would benefit such a lot from some examples.
Probably naively I was hoping to be able to catch the dreaded ViewExpiredException
with this code:
#Page(basePath = "/defaultErrorPage.xhtml")
public final class DefaultErrorPage extends DefaultErrorView {
}
...but all that happens after session timeout is that container security takes me
to the login page when I try to issue a get request (clicking on a h:link). Does
anyone know what I can do with this DefaultErrorView, anyone got an example?
Thanks!

In the JavaDoc of DefaultErrorView you see:
...
The class which extends this class will also be used as error-view in case of security violations
(if there is no special error-view configured via
{#link org.apache.myfaces.extensions.cdi.core.api.security.Secured#errorView()})
And in the Wiki you see e.g.:
#Secured
...
In case of a violation CODI will use the DefaultErrorView as navigation target (if configured).
...
and
(Security) Error pages
The following example shows how to create a default error page. It's just allowed to provide one default error page per application.
Instead of implementing ViewConfig it's required to implement the DefaultErrorView interface.
...
as well as the manual usage:
...
this.viewNavigationHandler.navigateTo(DefaultErrorView.class);
...
The Wiki also links a nice example and there you find:
http://code.google.com/a/apache-extras.org/p/myfaces-codi-examples/source/browse/community/src/main/java/org/apache/extras/myfaces/codi/examples/community/view/config/Pages.java
-> everything is fine with the documentation ;-)

Related

How to invalidate views for the current session in JSF?

We have an application (Mojarra 2.3) where a user can change a global filter of the data it sees. When that happens, I want to keep the session, but invalidate the active views (which are server side).
I found this question which enables you to count the number of views: How do I count the number of views in a user's JSF session (JSF 2.2)?
Based on that I figured I could remove the attribute in which the views are stored. I came up with this method:
public static void invalidateViews() {
final HttpSession session = Faces.getSession();
List.of("com.sun.faces.application.view.activeViewContexts",
"com.sun.faces.application.view.activeViewMaps",
"com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap",
"org.jboss.weld.context.ConversationContext.conversations")
.forEach(session::removeAttribute);
Faces.redirect(Faces.getRequest().getRequestURL().toString());
}
The com.sun.faces.renderkit.ServerSideStateHelper.LogicalViewMap was mentioned in the linked question's answer. I kind of guessed that it would not hurt to remove the other attributes. The answer also mentions that it is Mojarra only.
It seems to work so far, but I would like to ask this: should one clear server side views like this? And, if so, how can I support MyFaces as well?
It seems to work so far, but I would like to ask this: should one clear server side views like this?
Given that there is no standard API call for this, this is about the best you can do, yes. I have during the JSF 2.3 work requested for a more specific variant of this functionality to exist in the standard API because I needed to be able to destroy view scoped beans associated with a specific JSF view state (for the OmniFaces view scope unload functionality, see Hacks#removeViewState()). But this has unfortunately not yet been fleshed out because of difficulties with Portlets.
And, if so, how can I support MyFaces as well?
As seen in the OmniFaces Hacks helper class, the session attribute key for MyFaces 2.x is org.apache.myfaces.application.viewstate.ServerSideStateCacheImpl.SERIALIZED_VIEW and 4.x org.apache.myfaces.application.viewstate.StateCacheServerSide.SERIALIZED_VIEW.
By the way,
Faces.redirect(Faces.getRequest().getRequestURL().toString());
this is shorter:
Faces.refreshWithQueryString();

How to create a custom scope in Quarkus?

I tried to follow this instruction https://rpestano.wordpress.com/2013/06/30/cdi-custom-scope/
, but it's not working, because the methods of my custom Context are not fired.
You can declare custom scopes in Quarkus. However, Quarkus does not use a full CDI implementation, instead it has a lighter implementation that does not support everything you know from CDI the way you are used to. Reasons are multiple but mostly it is done in order to make it build time friendly.
CDI extensions are one of the things that are inherently runtime based and as such are a bad fit for Quarkus stuff. Instead, you will have to use a Quarkus extension to declare your scope/context. Let me give you some materials for that...
Here is a link to Quarkus CDI guide in general, it lists its limitations and how it compensates for it.
This bit in particular shows how to register a custom scope within extension. The method is as simple as:
#BuildStep
ContextRegistrarBuildItem customContext() {
return new ContextRegistrarBuildItem(new ContextRegistrar() {
public void register(RegistrationContext registrationContext) {
registrationContext.configure(CustomScoped.class).normal().contextClass(MyCustomContext.class).done();
}
});
}
And here is a link to how Narayana Quarkus extension uses this exact same API to register #Transactional. The underlying context class is very similar to what you would use in CDI (or in Weld), take a look at this class that Narayana uses for inspiration.

JSF FlowScoped direct entry point

sorry if this question has been asked but i couldn't find the answer.
I've converted some spring beans to cdi #Named and set the scope to FlowScoped. I've done this to fix a problem where session scoped beans were shared across multiple tabs and breaking the application in previously opened tabs.
I've got it partly working but i'm running into an issue with the entry point for the FlowScoped beans.
All the examples i have found use a page with a button, this button has an action which navigates to the flow entry point (i've created a blank bean-flow.xml file). is there a way to enter a flow scope directly from a link or from a faces redirect? I kind of need this for two reasons. Or maybe there is another work around? I use spring security to login and it is set with a default-target-url="/search/search.xhtml". I've got around this by creating another page and just using the below to do a redirect on load
ConfigurableNavigationHandler configurableNavigationHandler =
(ConfigurableNavigationHandler) FacesContext.getCurrentInstance()
.getApplication().getNavigationHandler();
configurableNavigationHandler.performNavigation("search");
the above works but the below doesnt
FacesContext.getCurrentInstance().getExternalContext().redirect("/search/search.xhtml");
Idealy i would also like to be able type straight into the address bar
http://localhost:8080/searchApp/search/search.xhtml?searchcriteria=somecriteria
At the moment when i do that or the faces redirect i get an error
javax.servlet.ServletException: WebBeans context with scope type annotation #FlowScoped does not exist within current thread
javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.apache.openejb.server.httpd.EEFilter.doFilter(EEFilter.java:65)
Any help at this point would be greatly appreciated.
It looks like you are trying to (ab)use a scope for which it was not directly meant to be used. Using the Deltaspike #WindowScoped is what you should use. It creates a scope per browser window or tab

Is it possible to get intellisense to work with Geb page objects?

I am guessing this is more of a groovy issue due to the geb implementation, but I'm wondering if there is any way to get intellisense to work with the geb page objects. I am also new to Java/Groovy (primarily C# development in the past) so there could be some things I'm just not quite understanding. I'm using Intellij, but I'd be happy if there is any IDE that could give me what I wanted.
As far as I can tell, Geb's implementation is that they have a Browser Class with a Page property and any methods or properties that are executed without the context of a specific Page instance will at runtime trigger a MissingMethod or MissingProperty exception, which Geb handles and re-routes to a corresponding method or property in the Page class that is currently set via the Page property in the Browser Class.
What this means for development is that when we're creating test cases, the IDE is unaware of which page instance is the current Browser Page property, thus no intellisense.
We experimented with creating instances of the pages and explicitly calling them, and also making our helper functions within the page classes static, both of which led to other issues.
For our shop, this is pretty much a deal breaker, but before we give up I wanted to see if any Geb or Groovy experts could offer some advice on how to get intellisense working, or could give us an indication of whether it is even possible.
EDIT: I found within the geb documentation a section on Strong Typing and IDE support that looked promising: http://www.gebish.org/manual/current/ide-and-typing.html#ide_support however, the examples provided fail. I pasted the example directly from geb documentation below, with comments showing where/why it fails:
HomePage homePage = browser.to HomePage //browser.to returns null, so this fails
homePage.loginButton.click()
LoginPage loginPage = browser.at LoginPage //browser.at returns boolean so this fails
SecurePage securePage = loginPage.login("user1", "password1")
//The only thing that I got to work, which seems messy is:
browser.to HomePage
HomePage homePage = browser.page
homePage.loginButton.click()
Ok... So, I had an old version of Geb somehow being pulled from my gradle cache. After fixing that problem and actually using Geb 0.9.2, the documented usage worked correctly: http://www.gebish.org/manual/current/ide-and-typing.html#ide_support

JSF, Exception Logging using a aopalliance MethodInterceptor

I would like to log the exceptions that are thrown when serving JSF files in the same way other exceptions are logged in our web application.
We annotate classes with logged exceptions with #LoggedExceptions and a MehtodInterceptor is matched against those classes with Guice AOP (This should be very similar for other implementations of aopalliance...)
The main problem is, that the method interceptor does not work. How can i intercept method calls on JSF-backing code?
You must replace the default el-resolver (<el-resolver> in faces-context.xml) with a Guice el-resolver, so that the jsf beans become instantiated by Guide.
Search for "Guice el resolver", or take this one (I can't guarantee it works). Also check this thread.
Also, read the top results of this google search

Resources