Why the fields in my login page disappear when I redirect after a ViewExpiredException? - jsf

I add the following lines to web.xml
<session-config>
<session-timeout>1</session-timeout>
</session-config>
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/login/login.xhtml</location>
</error-page>
to redirect to login page when the session expires and it is in fact redirecting but the fields name and password and the button "fazer login" disappear:
Heres the relevant code in the login page:
<div class="conteudo">
<div class="icone-produto"></div>
<div class="coluna-direita">
<div class="logo-produto" alt="Wplex-EP"></div>
<div class="card signin-card">
<h:panelGrid columns="1">
<h:dataTable value="#{funcionarioController.lista}"
rendered="false"></h:dataTable>
<h:dataTable value="#{escalaController.lista}" rendered="false"></h:dataTable>
<h:dataTable value="#{indisponibilidadeController.lista}"
rendered="false"></h:dataTable>
<h:dataTable value="#{programacoesController.programacoes}"
rendered="false"></h:dataTable>
<h:dataTable value="#{funcionarioController.lista}"
rendered="false"></h:dataTable>
<h:inputText class="texto" placeholder="Usuário"
value="#{loginController.login}" />
<h:inputSecret class="texto" placeholder="Senha"
value="#{loginController.senha}"/>
<h:commandLink id="fazerLoginId" action="#{loginController.isLoginOk}"
styleClass="btn btn-wplex mouseon">
Fazer Login
</h:commandLink>
</h:panelGrid>
</div>
</div>
</div>

The disappearing elements are actually all JSF components. This part,
<location>/login/login.xhtml</location>
must match the <url-pattern> of the FacesServlet entry in the very same web.xml in order to get it to parse the XHTML and render the JSF components as HTML. Apparently you don't have any one on *.xhtml. Perhaps it's *.jsf or /faces/*. You'd need to alter the <location> accordingly to match the <url-pattern> of the FacesServlet, so that it gets invoked. E.g. in case of *.jsf:
<location>/login/login.jsf</location>
An alternative is to just use an <url-pattern> of *.xhtml, so that you never need to fiddle and get confused with virtual URLs.
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
See also:
JSF Facelets: Sometimes I see the URL is .jsf and sometimes .xhtml. Why?

Related

How to create a link with a request parameter to a Servlet in JSF?

I want to use JSF component to implement a dynamic breadcrumb.
So my idea is to use this piece of code to pass parameter to my Servlet
<c:forEach items="#{sub_steps}" var="sub_step" varStatus="loop">
<h:link value="#{sub_step.name}" action="#{homeManager.redirect()}" ajax="false"> <!-- action="#{homeManager.redirect()}" -->
<f:param name="sub_step_id" value="#{sub_step.sub_step_id}" />
</h:link>
</c:forEach>
At this point, I see GET request coming going to my server but it is never handled by my servlet.
I have a managed bean with request scope like this:
#ManagedBean(name="homeManager", eager=true)
#RequestScoped
public class homeManager extends HttpServlet implements javax.servlet.Servlet
my method redirect method in my managed bean:
public String redirect(){
return "shop";
}
and an extract of my web.xml
<servlet>
<servlet-name>Shop</servlet-name>
<servlet-class>com.kino.front.homeManager</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Shop</servlet-name>
<url-pattern>/shop</url-pattern>
</servlet-mapping>
I expected a redirection to my url mapping shop with the parameter I set in markup so that my servlet can process the data and render my view with updated data.
Why my method is never called ?
Is it the proper way to pass value from JSF to Servlet ?
Solution is the replace h:link with
<a href="#{request.contextPath}/shop?sub_step_id=#{sub_step.sub_step_id}">
#{sub_step.name}
</a>
UPDATE:
or even better using JSF component (thanx to #Kukeltje's comment)
<h:outputLink value="#{request.contextPath}/shop?sub_step_id=#{sub_step.sub_step_id}">
#{sub_step.name}
</h:outputLink>
Beside other things (h:link does not have action and ajax attributes), your code does not work because h:link appends Faces Context path so it ends up referring to, for example,
/YourApp/Faces/shop instead of desired /YourApp/shop
Check out your page source before and after applying my suggestion and you will see the difference.

Why does the page change in JSF, but not the URL? [duplicate]

This question already has an answer here:
How to navigate in JSF? How to make URL reflect current page (and not previous one)
(1 answer)
Closed 7 years ago.
I have simple test web-application:
First Page - index.xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<html>
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
First page
<h:form>
<h:commandButton value="Go to Next page" action="next"/>
</h:form>
</h:body>
</html>
and Next Page - next.xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<html>
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
Next page
<h:form>
<h:commandButton value="Go to First page" action="index"/>
</h:form>
</h:body>
</html>
When I run my application i have that url on browser:
http://localhost:8080/Test/
and index.xhtml as first page.
Then when I click "Go to Next page" i have url
http://localhost:8080/Test/index.xhtml
and next.xhtml page. And when I click "Go to First page" page changes (to index.xhtml) but url its
http://localhost:8080/Test/next.xhtml
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
</web-app>
What should I do to make that the first page in my application has a URL,
http://localhost:8080/Test/index.xhtml
rather than
http://localhost:8080/Test/
?
I use Tomcat (TomEE)/7.0.37
Though it's an old thread, if someone is still looking for it can try "?faces-redirect=true". Like:
<h:commandButton value="Go to Next page" action="next?faces-redirect=true"/>
You're using command buttons (POST form submit buttons) for plain page-to-page navigation. This is completely wrong. You should be using plain buttons (GET navigation buttons) for this instead.
Replace the
<h:form>
<h:commandButton value="Go to Next page" action="next"/>
</h:form>
by
<h:button value="Go to Next page" outcome="next" />
Note: you don't need a <h:form> at all.
Your concrete problem of "one URL behind" is caused because you're seeing the URL of <h:form> itself being reflected in browser address bar instead of the URL of the form submit's result page. Open the JSF page in your webbrowser, rightclick and View Source and look closer at <form action> value.
See also:
Difference between h:button and h:commandButton
When should I use h:outputLink instead of h:commandLink?
What is the difference between redirect and navigation/forward and when to use what?
How to navigate in JSF? How to make URL reflect current page (and not previous one)

How to pass url parameters to JSF/xHTML?

I know this has been asked multiple times but mine is a slightly diff question.
I have a JSF page which queries a database and throws results, before i move to JSF, i used to do this in JSP and it was working fine.
When i was using JSP below is the link format i used to use
http://localhost:8080/blmdatabase/index.jsp?SearchString=Name&Category=Contact&Submit=Submit
My index.jsp used to capture the values using param.SearchString & param.Category, and 'Submit' used to activate the 'submit' button for the search.
How do i do the same for xHTML/JSF ?
Here is what i tried ...
http://localhost:8080/blmdatabase/index.xhtml?search=#{some search string}
In my index.xhtml
<td>
<f:metadata>
<f:viewParam name="search" value="#{databaseSearch.searchstring}" />
</f:metadata>
<p:inputText id="searchstring" size="20" maxlength="20" value="#{databaseSearch.searchstring}"/> <p:commandButton id="submit" icon="ui-icon-search" title="Search Database" update="panel" actionListener="#{databaseSearch.customerList}" />
</td>
in my databaseSearch.java
#ManagedBean(name = "databaseSearch")
#SessionScoped
public class databaseSearch implements Serializable {
public String searchstring;
//getter and setter for searchstring
}
Also, i would need it 'Submit' the form .... I am new to this, so please excuse me if this was already discussed before ...
Also if i specific index.html , my jsf components would not load, just a blank page. like if i go
http://localhost:8080/blmdatabase/
my primefaces components load fine, but if i do
http://localhost:8080/blmdatabase/index.xhtml
it does not, so now i am wondering how to pass the parameters :(
Web.xml
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
You could 'submit' your form adding <f:event type="preRenderView"> inside the <f:metadata> tag.
<f:metadata>
<f:viewParam name="search" value="#{databaseSearch.searchstring}" />
<f:event type="preRenderView" listener="#{databaseSearch.doSearch}" />
</f:metadata>
This way, you could implement how your bean will search for this specific query string
public void doSearch(ComponentSystemEvent event) {
if(!searchString.isEmpty()) {
// Do your search here
}
}
Your Faces Servlet maps to anything that's hold in the faces virtual folder:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
So http://localhost:8080/blmdatabase/index.xhtml URL won't be parsed through Faces Servlet. You must use http://localhost:8080/blmdatabase/faces/index.xhtml, note the use of faces/ before your index.xhtml file, also note that your <welcome-file> also points to faces/index.xhtml.
The downside of this URL pattern is that Faces Servlet would also process non-facelets resources like JavaScript files (.js), Style files (.css), images (*.png, *.jpg) and others. A better Faces Servlet mapping would be:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
In this way, Faces Servlet will process xhtml pages only and you won't need the faces virtual folder anymore. With this change, now you can access to http://localhost:8080/blmdatabase/index.xhtml with no problems.
you could use a method in the class dataBaseSearch:
if(searchString != null){
//execute a query in database
// return result to a variable(resultSet or list)
}
and use getter and setter to get the the resultSet or List
and render the result in a datatable.

UTF-8 in PrimeFaces 3.x

I have a very simple application,there is an inputtext in my index page and a button to go to page2.xhtml.
<h:body>
<h:form>
<h:inputText value="#{mainBean.testValue}"/>
<p:commandButton update="myoutput" value="ajax call" ajax="false"/>
<p:separator />
<h:commandButton action="#{mainBean.gotoPageTwo}" value="goto Page2"/>
<br/>
<h:outputText value="#{mainBean.testValue}" id="myoutput"/>
</h:form>
</h:body>
</html>
I tested this application with PrimeFaces 2.2.1 and there was no problem.
but after submit each of the above button, my UTF-8 characters will destroy.
I tested filter but it don't work.
Is it a bug in PrimeFaces 3.x?
Can any body solve this problem?
The web.xml example of the answer you found at PrimeFaces forum is incomplete. The <filter-mapping> is missing. Without that, the filter won't even run at all. Add it accordingly
<filter-mapping>
<filter-name>Character Encoding Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
When you're already on Servlet 3.0 (Tomcat 7, Glassfish 3, etc), an alternative is to use just the #WebFilter annotation on the class. Don't forget to remove the filter entry from web.xml.
#WebFilter("/*")
For a background explanation of the cause of this character encoding problem during PrimeFaces 2.x-3.x upgrade, see also Unicode input retrieved via PrimeFaces input components become corrupted

PrimeFaces 3.0M4 fileUpload doesn't fire after Login

After a lot of effort I got PrimeFaces 3.0M4 working on Tomcat 7.0.2 with Mojarra 2.1.3. The upload bean fires if I present the upload feature before login but doesn't fire if I login and then come for the file upload.
My filter definition is as follows:
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
<init-param>
<param-name>thresholdSize</param-name>
<param-value>2097152</param-value>
</init-param>
<init-param>
<param-name>uploadDirectory</param-name>
<param-value>c:\temp\</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<!-- Faces Servlet -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Faces Servlet Mapping -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
The login returns to the same page that holds the upload component. Infact I have two forms in the same Facelet defined as follows:
<h:form id = "loginForm">
<h:panelGrid columns="6" rendered="#{loginBean.loginSectionVisible}">
<h:messages errorClass="errorMessage" infoClass="infoMessage"
warnClass="warnMessage"></h:messages>
<h:outputText value="Username : "></h:outputText>
<h:inputText id="username" value="#{loginBean.username}"></h:inputText>
<h:outputText value="Password : "></h:outputText>
<h:inputSecret id="password" value="#{loginBean.password}"></h:inputSecret>
<h:commandButton value="Submit" action="#{loginBean.login}" type="submit"></h:commandButton>
</h:panelGrid>
</h:form>
<h:panelGrid columns="1" rendered="#{loginBean.uploadSectionVisible}">
<h:form enctype="multipart/form-data" prependId="false">
<p:fileUpload fileUploadListener="#{fileUploadBean.handleFileUpload}"
mode="advanced"
update="messages"
sizeLimit="100000"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>
<p:growl id="messages" showDetail="true"/>
</h:form>
I am almost certain that it has something to with the Filter. Any ideas? Would be much appreciated.
<h:panelGrid columns="1" rendered="#{loginBean.uploadSectionVisible}">
<h:form enctype="multipart/form-data" prependId="false">
Whether the upload form is processed depends on the outcome of #{loginBean.uploadSectionVisible} which you have there in the rendered attribute of a parent component. You seem to be requiring that the user is logged in in order to display the upload form. It will work if the #{loginBean} is in the session scope and you aren't doing any business logic in the getter method. But it will fail if the #{loginBean} is in request scope and/or you are doing the business logic based on request parameters.
You need to represent the logged-in user by a separate managed bean which is put in the session scope and fix the rendered attributes something like follows where #{user} is the session scoped bean representing the logged-in user:
<h:form ... rendered="#{not user.loggedIn}">
...
<h:commandButton action="#{login.submit}" ... />
</h:form>
<h:form ... rendered="#{user.loggedIn}">
<p:fileUpload fileUploadListener="#{upload.handle}" ... />
</h:form>
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated

Resources