jsf loosing url param after session-timeout - session-timeout

jsf page uses <f:viewParam> and <f:viewAction> in order to take url parameters and open the page normally.
I also used
<f:event type="preRenderView"/>
In that behavior is normally
On session lose if refreshing page or pressing enter in the url the page redirects to the login page where username and password are entered and the returns to the initial page having the parameters.
But in case session is lost and user clicks any button (an action button not a linl to a page) in the page the page redirects to the login page with the initial url but with no parameters
Example URL: localhost:8080/newProject/views/page1?id=1
In first case the same url is redirected to , but in second case it redirects to localhost:8080/newProject/views/page1 loosing the parameter id=1
Java code:
private Item item;
#EJB
ItemFacade itemFacade;
private String id;
public String getId(){
return id;
}
public void setId(String id){
this.id=id;
}
public void init(){
item= itemFacade.find(id);
}
JSF code:
<f:viewParam name="id" value="#{myBean.id}"/>
<f:viewAction value="#{myBean.init()}" onPostback="false"/>

Related

open a menuitem page in a new tab in primefaces

I have a xhtml page with a session scoped backing bean. Now i have to open this page in a new tab with right click open link in new tab.
When this page opens the model class of the backing bean must be cleared.
I have used the following code:
<p:menuitem value="Details" action="#{beanMB.clearDetailModel()}"/>
backing bean code:
public void clearDetailModel()
{
memberModel=null;
......
return "/pages/member/MemberDetails.xhtml?faces-redirect=true";
}
The above code clears the session scoped model but it does not open the page in new tab.
Is there any method to open the page in new tab with the above code or is there any alternate way for the above problem?.Any help would be appreciated.
Thank you.
You can try this:
You need to put the following code in MemberDetails.xhtml page.
<f:metadata>
<f:event type="preRenderView" listener="#{beanMB.clearDetailModel}"/>
</f:metadata>
and use url in menuitem to open your page.
<p:menuitem value="Details" url="/pages/member/MemberDetails.xhtml" />
you need to modify your backing bean code as follows:
public void clearDetailModel()
{
if (isNewRequest()){
memberModel=null;
......
}
}
public boolean isNewRequest() {
final FacesContext fc = FacesContext.getCurrentInstance();
final boolean getMethod = ((HttpServletRequest) fc.getExternalContext().getRequest()).getMethod().equals("GET");
final boolean ajaxRequest = fc.getPartialViewContext().isAjaxRequest();
final boolean validationFailed = fc.isValidationFailed();
return getMethod && !ajaxRequest && !validationFailed;
}
Here method isNewRequest() checks if the request is new or not if this is not checked your method clearDetailModel() will be called each time new request is made.

f:viewParam not reading url on session lost

I am accessing my jsf page using <f:viewParam> and <f:viewAction>
My page is accessing fine where parameter is read from url and getter and setter are accessed
My problem is that when this page session is lost and i refresh the page to rerun i will be directed to a login page and username and password are written and then redirected to my page but <f:viewParam> is not reading the url
I debuged my code it is not accessing the getter and setter of the variable where the variable stays 0 instead of being set to the id in the url
URL: localhost:8080/myProject/views/myPages/bookList?id=1
JSF code:
<f:viewParam name="id" value="#{bean.id}"/>
<f:viewAction value="#{bean.init()}" onPostback="false"/>
Java code:
private BookList bookList;
#EJB
BookFacade bookFacade;
private String id;
public String getId(){
return id;
}
public void setId(String id){
this.id=id;
}
public void init(){
//good scenario id is sent 1 while session is lost id is sent 0
bookList = bookFacade.find(id);
}

Showing a dynamic image that depends on a Request Parameter

I'm trying to build a user profile page to show some details about my users.
The url of the page is something like profile.xhtml?username=randomString.
So, what I've to do is loading all the data of randomString's user.
It goes everything fine since it's the moment to show user's image.
I'm using PrimeFaces with graphicImage component, but the problem is that it causes a NEW request to get the image, so the request parameter is actually lost and the getAvatar() method receives a null parameter.
One solution may be making the bean SessionScoped, but it will take data from the first requested user and it will show them even if randomString will change, so I'm asking for help :
How can I show a dynamic image from database that depends on a request parameter?
Thanks :)
EDIT : New code following BalusC's reply
JSF Page :
<c:set value="#{request.getParameter('user')}" var="requestedUser"/>
<c:set value="#{(requestedUser==null) ? loginBean.utente : userDataBean.findUtente(request.getParameter('user'))}" var="utente"/>
<c:set value="#{utente.equals(loginBean.utente)}" var="isMyProfile"/>
<pou:graphicImage value="#{userDataBean.avatar}">
<f:param name="username" value="#{utente.username}"/>
</pou:graphicImage>
(I'm using this vars because I want the logged user's profile to be shown if page request il just profile.xhtml without parameters)
Managed Bean :
#ManagedBean
#ApplicationScoped
public class UserDataBean {
#EJB
private UserManagerLocal userManager;
/**
* Creates a new instance of UserDataBean
*/
public UserDataBean() {
}
public Utente findUtente(String username) {
return userManager.getUtente(username);
}
public StreamedContent getAvatar(){
String username = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("username");
System.out.println(username==null);
Utente u = findUtente(username);
return new DefaultStreamedContent(new ByteArrayInputStream(u.getFoto()));
}
}
What's wrong with it?
username is always null!
EDIT 2 : Added reply to BalusC
Yeah, because the getAvatar() method calls findUser() as I need to find the user's entity with the username passed as parameter (<f:param> won't allow me to pass an object!).
So findUser() throws an exception because I'm using entityManager.find() with a null primary key!
Btw, I'm absolutely sure that both #{utente} and #{utente.username} are not null because the panel that contains the image is rendered only if #{utente ne null} and username is its primary key!
So I can't really check the HTML output!
I'm afraid that #{utente} is lost when I call getAvatar() as getting an Image requires a new http request
Pass it as <f:param>. It will be added during render response.
<p:graphicImage value="#{images.image}">
<f:param name="id" value="#{someBean.imageId}" />
</p:graphicImage>
The #{images} helper bean can just look like this:
#ManagedBean
#ApplicationScoped
public class Images {
#EJB
private ImageService service;
public StreamedContent getImage() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getRenderResponse()) {
// So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
return new DefaultStreamedContent();
}
else {
// So, browser is requesting the image. Get ID value from actual request param.
String id = context.getExternalContext().getRequestParameterMap().get("id");
Image image = service.find(Long.valueOf(id));
return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
}
}
}
As the above helper bean has no request based state, it can safely be application scoped.

Hit a bean method and redirect on a GET request

I'm using JSF 2 and PrimeFaces 2.1 on GlassFish.
I have a page that is intended to allow people to perform an action after following a callback URL (e.g. as link embedded in email or as callback URL parameter of some external authentication or payment service). In my case I need to reset the password. The callback URL has a token GET parameter like so:
http://example.com/app/resetPasswordForm.jsf?token=abc123
On page load of resetPasswordForm.jsf, I need to check if the token is valid and redirect to the main app screen if it's not valid.
My thinking is to have a bean method like:
public String resetPasswordHandler.showResetForm(String token) {
if /* token is valid */ {
return "resetPasswordForm.jsf";
} else {
return "main.jsf";
}
}
But how would I cause that method to get hit on page load?
Not sure how to proceed -- suggestions are welcome.
Use <f:viewAction> to trigger a bean method before rendering of the view and simply return a navigation outcome (which will implicitly be treated as a redirect).
E.g.
<f:metadata>
<f:viewParam name="token" value="#{authenticator.token}" />
<f:viewAction action="#{authenticator.check}" />
</f:metadata>
with
#ManagedBean
#RequestScoped
public class Authenticator {
private String token;
public String check() {
return isValid(token) ? null : "main.jsf";
}
// Getter/setter.
}
If you're not on JSF 2.2 yet, then you can use the <f:event type="preRenderView"> workaround in combination with ExternalContext#redirect().
<f:metadata>
<f:viewParam name="token" value="#{authenticator.token}" />
<f:event type="preRenderView" listener="#{authenticator.check}" />
</f:metadata>
with
#ManagedBean
#RequestScoped
public class Authenticator {
private String token;
public void check() throws IOException {
if (!isValid(token)) {
FacesContext.getCurrentInstance().getExternalContext().redirect("main.jsf");
}
}
// Getter/setter.
}
See also:
Communication in JSF 2.0 - Processing GET request parameters
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
How do I process GET query string URL parameters in backing bean on page load?

Iceface 2.0 commandLink partial submit doesn't work

I have a page which takes in request params for place, then generate information,
for example, http://example.com/xxx/weather.jsf?place=california.
The purpose of doing this is to let user bookmark the link.
In the weather.jsf, there are two outputtext and a commandlink:
Humidity : <ice:outputText value="#{weatherBean.humidity}"/>
Visibility : <ice:outputText value="#{weatherBean.visibility}"/>
<ice:commandLink id="likeButton"
value="Like"
actionListener="#{weatherBean.doLike}" />
In the managedBean:
#ManagedBean(name="weatherBean")
#RequestScoped
public class WeatherBean
{
String humidity;
String visibility;
int numLike;
#PostConstruct
public void init()
{
System.out.println("init called");
HttpServletRequest request= (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
String place = request.getParameter("place");
setHumidity(WeatherDao.getHumidity(place));
setVisibility(WeatherDao.getVisibility(place));
setNumLike(GeneralDao.getNumLike());
}
public void doLike(ActionEvent event)
{
System.out.println("doLike called");
GeneralDao.addNumberLike();
}
}
Alright, the page generated perfectly.
However, when I click the doLike commandLink,
it always triggers the init method first, then call doLike method.
Since the request param is empty, all the other values reset.
Is there any way to prevent a refresh of the page or calling of init method?
I tried partialsubmit or immediate, but no luck.
Your bean is #RequestScoped, so after executing the JSF lifecycle, your bean instance is lost, until the next request comes in, at which point you get a new instance of your bean, and the PostContruct re-executes.
Try changing the scope of your bean to something longer lived, like #ViewScoped.

Resources