Why JSF POST requests don't work with PrettyFaces - jsf

I have been using JSF (MyFaces) with PrettyFaces for a while. Everything works perfectly, excepting POST requests.
The only problem I have is that I can’t make POST requests to any of the pages that are rewritten by PrettyFaces.
I would really appreciate your help, because it’s a show stopper.
pretty-config.xml
<url-mapping id="market-view-item">
<pattern value="/market/#{viewItem.itemId}" />
<view-id value="/market/view-item.xhtml" />
</url-mapping>
pom.xml
<dependency>
<groupId>org.ocpsoft.rewrite</groupId>
<artifactId>rewrite-servlet</artifactId>
<version>2.0.5.Final</version>
</dependency>
<dependency>
<groupId>org.ocpsoft.rewrite</groupId>
<artifactId>rewrite-config-prettyfaces</artifactId>
<version>2.0.5.Final</version>
</dependency>
I used 2.0.4.Final until today. I hoped that it will work by upgrading to 2.0.5, but nothing.
web page form:
<h:form prependId="false">
<p:inputTextarea rows="3" style="width:450px; margin:5px 0;" autoResize="false"/>
<h:commandButton action="#{test.doSomething}" class="pg-button" value="Add comment"/>
</h:form>
CDI bean:
#Named("test")
#RequestScoped
public class TestB {
public void doSomething() {
System.out.println("I work.........");
}
}
Any ideas why POST requests are not executed? Whatever I do, they just don’t happen. No error at all. Just nothing.
When I press the submit (Add comment) button, Chrome makes a request (ajax / non-ajax (I tried both)), but method doSomething is not triggered.
I tried withing bean viewItem also (the one specified in pretty config), but nothing. I tried in 100 ways…
I have to mention that all pretty faces config mappings work perfectly on GET requests, just that I can’t post from them.
I couldn't find any solution/answer to this until now.
I would really appreciate any help.
Thanks a lot!

CDI bean:
#Named("test")
#RequestScoped
public class TestB {
public void doSomething() {
System.out.println("I work.........");
}
}
Is it possible that your 'CDI' bean lacks constructor method and that could be causing the problem here?
I have been using TomEE+ ever since TomEE+ 1.5.1 'SNAPSHOT', then I migrated to TomEE+ 1.5.2 'SNAPSHOT' as soon as it was available, and then I migrated to TomEE+ 1.6.0 'SNAPSHOT', and always try to use latest versions of the 'SNAPSHOT' JAR file. I only use 'SNAPSHOT' versions this way, and 'SNAPSHOT' = 'latest and greatest'. :)

First of all, thanks for helping. It is something strange, that's why I couldn't isolate the problem (to get it happen in another project), which is not executing the POST requests at first try, but from the second one.
I have removed the filters I had in web.xml without any difference. The same behavior.
I've just had the idea of testing the project in other Tomee version than 1.5.2. Surprisingly, dev version 1.6.0 from 29.07.2013 seems to don't have this problem. Why didn't I think at this sooner? :( I had to write separate Servlet components for my post functionalities. Aaaah!
Well, this means that not PrettyFaces was problematic (Huraay!), but, probably, Apache MyFaces, CDI impl. or something else in Tomee.
Uf...I'm so happy that it works now.
Thanks again for trying to help.
///////////////////////////////News//////////////////////////////////
It seems that it didn't work in other versions of Tomee neither.
The problem was having a c:forEach in that page (inside a custom component used in that page), even though the commandButton was not inside the loop. By switching to ui:repeat, the problem is gone in all versions of Tomee.
It is probably a bug in MyFaces, because Glassfish 3.1.2.2 (with Majorra) doesn't have this problem. (tested)
///////////////////////////////News 2//////////////////////////////////
Ha...even more interesting.
If h:form is after c:forEach, the POST method is not triggered at first try. It works just from the second try. That's the original problem.
If h:form is before c:forEach, the Post method (action of the form) is executed properly from the first time/click.

Related

CDI conversation discontinues, when multipart/form-data is used

We use JSF 2.1, Glassfish 3.1.
We have a similar file upload solution to the one explained here: http://balusc.blogspot.hu/2009/12/uploading-files-with-jsf-20-and-servlet.html
The problem is that when the form is set to multipart/form-data, a new conversation is started on post, which breaks our app. Of course we could store information in SessionScoped beans instead, but we would like stick to ConversationScope if possible. We didn't try it with omnifaces ViewScoped.
Did anyone faced this issue? thx
We tried BalusC's answer and it works fine. Attaching the 'cid' to the rendered form's action works. In fact, if there is an input field named 'cid', JSF can return to the conversation. This latter solution is simpler.
<input type="hidden" name="cid" value="#{conversation.id}" />
Thanks!

GlassFish 3.1.2.2 JSF upgrade [duplicate]

I'm facing the following exception in a very simple JSF 2 page after adding <h:form>:
java.lang.IllegalStateException: Cannot create a session after the response has been committed
at org.apache.catalina.connector.Request.doGetSession(Request.java:2758)
at org.apache.catalina.connector.Request.getSession(Request.java:2268)
I'm using Mojarra 2.1.3 and PrimeFaces3.0M4, on Tomcat 7.0.22 and JDK 7.
The page is a very basic data table:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form>
<p:dataTable var="car" value="#{tableBean.cars}">
......
</p:dataTable>
</h:form>
</h:body>
</html>
The page shows correctly on the browser, but on the console I see the exception. The Exception does disappear if I remove the <h:form>.
How is this caused and how can I solve it?
This is a known problem and has been reported by yours truly as issue 2215. This will occur when the response buffer has overflowed (due to large content) and the response is been committed before the session is been created. This is result of bit overzealous attempts of Mojarra to postpone "unnecessary" session creation as much as possible (which is at its own a Good Thing though).
Until they get it fixed, there are several workarounds:
Create a Filter which does HttpServletRequest#getSession() before FilterChain#doFilter(). Advantage: no need to change JSF configuration/code. Disadvantage: when you want to avoid unnecessary session creation yourself as well.
Call ExternalContext#getSession() with true in bean's (post)constructor or preRenderView listener. Advantage: actually, nothing. Disadvantage: too hacky.
Add a context parameter with name of com.sun.faces.writeStateAtFormEnd and value of false to web.xml. Advantage: unnecessary session creation will be really avoided as opposed to #1 and #2. Disadvantage: response will now be fully buffered in memory until </h:form> is reached. If your forms are not extremely large, the impact should however be minimal. It would however still fail if your <h:form> starts relatively late in the view. This may be combined with #4.
Add a context parameter with name of javax.faces.FACELETS_BUFFER_SIZE and a value of the Facelets response buffer size in bytes (e.g. 65535 for 64KB) so that the entire HTML output or at least the <h:form> (see #3) fits in the response buffer. Advantage/disadvantage, see #3.
Add a context parameter with name of javax.faces.STATE_SAVING_METHOD and value of client to web.xml. Advantage: session will not be created at all unless you have session scoped beans. It also immediately solves potential ViewExpiredException cases. Disadvantage: increased network bandwidth usage. If you're using partial state saving, then the impact should however be minimal.
As to why the problem disappears when you remove <h:form>, this is because no session needs to be created in order to store the view state.
Update: this has as per the duplicate issue 2277 been fixed since Mojarra 2.1.8. So, you can also just upgrade to at least that version.
With the new version 2.1.21 released yesterday of javax.faces this problem seems to have disappeared.
Declare the new version:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.1.21</version>
</dependency>
and replace the javax.faces.jar in the glassfish modules folder replacing the javax.faces.jar for the new version 2.1.21.
In my case (myfaces-2.2.8 & Tomcat 8.0.23) the Problem was a typo in the welcome-file of web.xml.
While debugging i saw, that Tomcat created as expected a 404, but somehow myfaces tried to access afterwards the Session, which caused then a java.lang.IllegalStateException: Cannot create a session after the response has been committed.
Using a valid page in welcome-file of web.xml fixed the Problem for me.
You may need to add an <f:view> and </f:view> before and after h:form elements, plus add the link to you html tag for jsf tags
<html xmlns:f="http://java.sun.com/jsf/core">
for this to work.
If you are using Spring MVC and call is made by Spring Forms then we should use GET method instead of POST(to fetch data) and there should be no input field we can use intead.

How to include pages in a JSPX and Trinidad project in run-time without breaking the JSF lifecycle?

I am struggling to figure out a way to include dynamically determined pages in run-time in a JSPX and Trinidad project. You will have an idea when you see what I have, which is:
<tr:panelAccordion>
<tr:showDetailItem
text="Test tab">
<jsp:include page=".test.jspx" /> <!-- This part is working fine -->
</tr:showDetailItem>
<jsp:scriptlet>
BackingTest backing = (BackingTest) session.getAttribute("backingTest");
for (CaseTabConfigurationDTO tab : backing.getTabs()) {
java.io.File f = new java.io.File(request.getRealPath(tab.getPagePath()));
if (f.exists()) {
pageContext.include(tab.getPagePath(), true);
}
}
</jsp:scriptlet>
</tr:panelAccordion>
jsp:include part is working fine, nothing is breaking the JSF lifecycle.
jsp:scriplet part is successful for including the correct pages. However, it is breaking the later actions in JSF lifecycle including still persisting backing beans of dialogs opened using useWindow="true".
In order to be make it complaint with Facelet, thus not breaking JSF lifecycle. I tried using tr:forEach, c:forEach, ui:include, ui:repeat approaches without any luck of actually including pages.
Can you share a proper solution for it? Thanks in advance!
You probably want to reconfigure your project so you can use Facelets with Trinidad. After reconfiguring your project can use Facelets for templating. You will end up using xhtml instead of jspx though.
See also:
When to use <ui:include>, tag files, composite components and/or custom components?
How to include another XHTML in XHTML using JSF 2.0 Facelets?

JSF commandLink not working on redirected error page

I'm redirecting all exceptions to a simple error page with the following entry in my web.xml file:
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error.xhtml</location>
</error-page>
My error page contains:
<ice:form id="errorForm">
<ice:outputText value="#{guiProps.UnknownError}"/><br/><br/>
Click <ice:outputLink value="/"> here</ice:outputLink> to attempt to return to the previous page.<br/>
Click <ice:commandLink value=" here" action="#{UserBean.logoutAction}"/> if you are unable to do so.
</ice:form>
The problem is, the commandLink DOES NOT work when it's clicked. The logoutAction method is never fired. You get a brief hourglass, I observe a little bit of XMR action (via Chrome browser) but nothing really happens. I've also tried using vanilla JSF tags (h:commandLink, h:form, etc) and the same thing happens, so its a JSF problem, not an ICEfaces problem
Also weird...this problem only happens using Glassfish v2.1.1, not v2.1. I don't know if it's a v2.1.1 bug, per se, but in any case, if there is a way to work around it or a way of figuring out what is going on, I'd appreciate any help, because we are certainly using v2.1.1.
Are you sure it is supposed to be UserBean and not userBean?
#{userBean.logoutAction}

JSF and richfaces: h:commandlink in richfaces table not working properly

When using h:commandlink(or commandbutton) inside a rich:dataTable, the action specified is never invoked, neither is the corresponding managed bean instantiated(whether it is at request or session scope)...
instead, the same request is performed.. (page reloads)..
have seen what appeared to be similar issue on forums, but is not actually the problem i am having..
the h:commandlink /button work ok outside of the rich:datatable..
Does anyone have any advice?
here is a code snippet:
<h:commandLink id="commLink" actionListener="#{hBean.test}" action="#{hBean.viewTranslation}">
<h:outputText value="#{trans.translationName}"/>
</h:commandLink>
</rich:column>
The bean is apparently request scoped and the datamodel is not been loaded during bean's construction (at least, during apply request values phase of the subsequent request). You need to preserve the same datamodel for the subsequent request, else JSF cannot locate the row item associated with the clicked link. The most straightforward way is to load the datamodel in the bean's constructor or #PostConstruct method.
A quick fix/test is to put bean in session scope. The datamodel will then be saved in the session scope and be available in the subsequent request. But this has more impact on user experience (e.g. unexpected results when having the same page opened in different browser windows/tabs in the same session). If you're already on JSF 2.0 (which is likely not the case since you're using RichFaces), then the new view scope would have been the solution.
Related questions:
h:commandLink is not been invoked - contains an overview of all possible causes of this behaviour.
If you are using RichFaces 3.0.0 through 3.3.3, use the tag a4j:keepAlive. It will works even with request scope.

Resources