Double call to action - prettyfaces - jsf - jsf

I am making a page in which I call a PrettyFaces page-load action method:
<url-mapping id="informes-perfil">
<pattern value="/informes/#{informesPerfilMB.codigo}" />
<view-id value="/faces/informes_perfil.xhtml" />
<action onPostback="false">#{informesPerfilMB.load()}</action>
</url-mapping>
For some reason, the informesPerfilMB.load() action is called twice, and the parameter value in the second call is 'null' or 'RES_NOT_FOUND'.
Here is my load method:
public void load() {
if (isPostBack) {
isPostBack = false;
try {
System.out.println(codigo);
informe = informeEJBServiceLocal.getByCodigo(codigo);
this.buscarInformeIngreso();
this.buscarInformeOtroIngreso();
} catch (EJBServiceException e) {
e.printStackTrace();
}
}
}
The isPostBack variable is initialized to false, so this should prevent the method from being called again, but for some reason it is.
This code first prints String: dcc509a6f75849b.
Then when the load is repeated, it prints this: RES_NOT_FOUND
I hope this code helps explain what is happening enough to solve my problem, Thanks.

I've seen this happen on my similar system in the past. I think it's an interaction between faces and prettyfaces with missing files. The RES_NOT_FOUND part comes from the network traffic. There's some likely faces resource (or stylesheet) that it's trying to find in libraries and when it can't, it essentially causes the browser to go to the URL /informes/RES_NOT_FOUND. For some reason, it would often find that resource if I refreshed the page and wouldn't issue a RES_NOT_FOUND URL.
First, I'd open up the page source, and you'll find RES_NOT_FOUND, likely along with the stylesheets. Given the position of it, you might be able to correlate it to the resources loaded in your xhtml files and see which one's missing. If that doesn't help, try the developer tools and see which resources are loaded and which are not. Then make sure the resource is present, deployed, and is in the correct location.
If it's not something that you can control (like a library resource), you can always make sure your setCodigo function ignores values of "RES_NOT_FOUND".
public void setCodigo(String value) {
if (!"RES_NOT_FOUND".equals(value)) {
this.codigo = value;
}
}
You may be able to modify your security or servlet-mapping settings (in WEB.XML) to prevent URLs ending in RES_NOT_FOUND from getting to the prettyfaces pages, but I don't know enough about it to do that.

First, the reason your isPostBack variable is called twice is most likely because you have two instances of the bean, not one singleton instance. There are a few reasons this could be happening:
Your bean is request scoped and multiple requests are being made to the page.
Your bean is being created multiple times by parts of your application that use it and call the load() method.
I also believe it is possible your method is being called twice because of the way you have written your EL expression (I'm not 100% sure):
<action onPostback="false">#{informesPerfilMB.load()}</action>
^^
Note the parenthesis at the end of your method expression. I believe this will force EL to evaluate the method when the expression is evaluated. Your method expression should look like this:
<action onPostback="false">#{informesPerfilMB.load}</action>
You should also check for other places in your application where this method might be called.
Please let me know if this helps.

Related

Load bundle string (in right language) when value depends on bean condition

I have a Problem with jsf and multiple languages. So my strings are in WEB_INF/classes/texte_<lang>.properties files. And are accessed for example like that
<h:outputLabel value="#{messages.err_text}"/>
which works fine.
The problem is, i have <h:outputLabel... element where i want to show an error message depending on the error. I would like something that works like this:
<h:outputLabel value="#{someBean.errMsg}/>
With a Bean like that
#ManagedBean()
#SessionScoped
public class SomeBean{
public String getErrMsg(){
if(something){
return "#{messages.err_text}"
}else if(somethingElse){
return "#{messages.err_text2}"
}else{
return "#{messages.err_text3}"
}
}
}
Just to be clear it doesn't work that way. I'm looking for a similar solution (or any solution) that works.
Thanks for reading.
Don't do it that way. The model shouldn't be aware of the view. Localization also doesn't strictly belong in the model. The model should instead prepare some state which the view has to be aware of.
One way would be:
public String getErrMsg(){
if (something) {
return "err_text";
} else if (somethingElse) {
return "err_text2";
} else {
return "err_text3";
}
}
<h:outputLabel value="#{messages[someBean.errMsg]}" />
Other way would be returning an enum as demonstrated in the following related questions: Localizing enum values in resource bundle and How to use enum values in f:selectItem(s).
The reason why what you have now is not working, is because the value attribute of the outputText is evaluated as a plain String, and not as an EL expression.
Going by what you are working with now, the best way to proceed is to inject the resource bundle directly into your bean:
#ManagedProperty("#{messages}")
ResourceBundle messages;
And then,
public String getErrMsg(){
if(something){
messages.getString("err_text");
}
}
In case you're not aware, traditionally, error messages are presented using the h:message component.
On an unrelated note to your original question, you should also know that it's not generally advisable to have processing logic buried in your getter. For one thing, the getter is called multiple times during the rendering of your page. Also for this to work properly, you should be able to guarantee that the value something will stay consistent across the entire lifecycle of a single JSF request

Customize action taken when not authenticated

I have a Symfony 2.1 application where, depending on the url requested, I want to take a different action when the user's credentials have expired. I'm using the fos_userbundle which, by default, redirects to the login url. In my case, instead of redirecting, I want to return special response that the client will handle.
Idea #1:
I'm not sure exactly what I need to do to accomplish this. I've stepped through the code and found where the Symfony\Component\Security\Http\Firewall\ExceptionListener is catching the exception that was thrown and eventually a RedirectResponse is set. I think I need to hook into here somewhere and set a different response but I haven't found it yet.
Idea #2:
I think I maybe need to setup another firewall that will handle the missing credentials differently. This seems like it would be a lot more work and doesn't quite feel right.
Both of my ideas may be way off base. It seems like it shouldn't be that difficult of a think to figure out, but I've searched high and low and can't find an answer.
I dont know if they've changed the format for kernel listeners in 2.1 vs 2.0, but perhaps you could create a listener that handles the onKernelRequest method and checks to see if they are authenticated.
kernel.listener.pageloadlistener:
class: Acme\DemoBundle\EventListener\PageLoadListener
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
class PageLoadListener
{
public function onKernelRequest(GetResponseEvent $event)
{
//Do whatever here, you could pass in the security context in the construct of this class to get the user
}
}

Richfaces: NoSuchFieldElementException AjaxChildrenRenderer for HTML Tag

I use richfaces 3.3.3.Final with Seam and facelet.
I have plugged a profiler on my application and I have a weird behavior.
When I log all exceptions thrown by the application, I have more than 10 000 NoSuchFieldElementException in 10 minutes.
After many search, I found the problem:
When I started an ajax request by a4j:support, the NoSuchFieldElementException is thrown by the AjaxChildrenRenderer in these lines (199-202):
String componentType = (String) component.getClass().getField("COMPONENT_TYPE").get(null);
result = _specialComponentTypes.contains(componentType);
The component variable is a UIInstructions and it has no "COMPONENT_TYPE" field. So, the exception is normal.
This exception is thrown for each html block contained in my page. For example:
<h2>Test</h2>
<span></span>
When I reRender a block with html tag, the exception is thrown.
I have very complex page, so I get many of this exceptions.
How I can do to avoid this exception ? May be a parser option to avoid to go in this class for html block.
Thanks for your help.
As a temporary solution, you could modify the source code to add an instanceof check which should skip that block and then ship the modified source code with your webapp. Ship it either as a single class with identical package/class name in web project itself (javadoc-document it properly), which would always have preference in classloading over the one in the JAR, or as a modified and rebuild JAR file.
if (!(component instanceof UIInstructions)) {
String componentType = (String) component.getClass().getField("COMPONENT_TYPE").get(null);
result = _specialComponentTypes.contains(componentType);
}
As a lasting solution, you should report it as a performance issue to the RichFaces guys so that they get it fixed and release a new update, but I don't think that they will prioritize 3.3.x updates that much. I.e. it might take longer than you'd expect.

JSF resource versioning

I am trying to put versioning around the resources in an application.
If I do like this resources/js/1_0_0/mainscript.js
It does not work. It says RESOURCE_NOT_FOUND
but when I do like this
resources/js/mainscript.js/1_0_0.js
It works. I do not like the way it is organized in the second way. First one looks cool. Any Idea?
I am using Tomcat 7.0, JSF 2.0.9
Update: I was checking primefaces-2-2.1.jar. Since when I checked the page source, I saw this
/javax.faces.resource/jquery/jquery.js.xhtml?ln=primefaces&v=2.2.1">
Then I looked at META-INF/resources/primefaces/jquery/jquery.js
They did not have any versioning in there but how did it append v=2.2.1 in the head
If I do like this resources/js/1_0_0/mainscript.js
It does not work. It says RESOURCE_NOT_FOUND
This will work if you specify js as library name.
<h:outputScript library="js" name="mainscript.js" />
However, this is not the proper usage of a resource library. Rather introduce one.
resources/default/1_0_0/js/mainscript.js
Then you can specify it as follows:
<h:outputScript library="default" name="js/mainscript.js" />
They did not have any versioning in there but how did it append v=2.2.1 in the head
It's done by PrimeResource which kicks in on resource requests with ln=primefaces parameter. Its getRequestPath() has the following implementation:
#Override
public String getRequestPath() {
return super.getRequestPath() + "&v=" + Constants.VERSION;
}
Where Constants is the PrimeFaces specific constants file which is updated with every PF version.

How to forward a request to non-JSF page in action method?

I want to forward request to a non-JSF page from JSF action method.
I am using below code in my JSF action :
public String submitUserResponse() {
// ...
parseResponse("foo.jsp", request, response);
// ...
return "nextpage";
}
private String parseResponse(String uri, HttpServletRequest request, HttpServletResponse response) {
if (uri != null) {
RequestDispatcher dispatcher = request.getRequestDispatcher(uri);
dispatcher.forward(request, response);
return null;
}
// ...
return "xxxx";
}
The submitUserResponse() action method is being called when user clicks the submit button from the JSF page and this method returns nextpage string. Here the request forwards to next JSF page in normal flow. But in my requirement, I need to forward request to next non-JSF page. It is going, but it is displaying below exception in server.
java.lang.IllegalStateException: Cannot forward after response has been committed
I observed that code lines between parseResponse(...) and return "nextpage"; are still being executed after forwarding my request using dispatched.forward(uri). Same thing happened with response.sendRedirect(url). How is this caused and how can I solve it?
Here my doubts are: 1.why next lines of code is being executed after forwarding my request using dispatched.forward(uri) . Same thing happening in response.sendRedirect("").
Because you didn't call return to jump out of the method block. The include(), forward() or sendRedirect() really doesn't have some magic that they automagically does that. Those are still just Java methods like any other (except of System#exit() of course). They will be invoked in order and the code will just continue until end of method block or return statement. It's just all about the code flow you write and control yourself.
That said, the normal JSF practice is that you should use ExternalContext#dispatch() or ExternalContext#redirect() for this (the first is applicable in your case). Not only it keeps your code free from unnecessary "under-the-hood" clutter in JSF code such as the Servlet API, but it also removes the need to call FacesContext#responseComplete() which you could also have done to fix your initial IllegalStateException problem.
In a nutshell: replace your code by
public void submitUserResponse(){
String uri = "foo.jsp";
FacesContext.getCurrentInstance().getExternalContext().dispatch(uri);
}
That's all. No need to unnecessarily dig the Servlet request/response from under the JSF hoods. Note that the method is declared void. This is perfectly acceptable, although some know-it-better like IDE's will complain about it, if so, then just ignore it or replace by String and add return null;.
See also:
How to navigate in JSF? How to make URL reflect current page (and not previous one)
ExternalContext.dispatch() not working
This worked for me:
FacesContext.getCurrentInstance().getExternalContext().dispatch("/ServletUrl");
(pay special attention to the fwd slash '/')

Resources