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);
}
Related
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"/>
i know there are many similar threads but no like mine:
I have a requestscope bean:
#ManagedBean
#RequestScoped
public class Bean implements Serializable{
private String username = ""; //managed by textbox
private String password = ""; //managed by textbox
private String id ="-";
//Load the Parameter as usual:
#PostConstruct
public void fetchParams(){
System.out.println("FETCH PARAMS");
FacesContext facesContext = FacesContext.getCurrentInstance();
String id = facesContext.getExternalContext().getRequestParameterMap().get("id");
if(id == null || id.length() == 0) return;
setId(id);
}
// getters & setters
public void doSomething(){ //executed when clicked on the sumbit-button on the jsf-site
StaticFunctions.doSomething(this);
}
}
The code does following:
it retrieves the get-parameter "id" and saves it into String id (confirmed by string.out....).
But when the method doSomething() is executed and the previously stored "id" is read and returns "-" (like nothing happened).
why is this so?
Your ManagedBean is #RequestScoped and will be destroyed at the end of the request. When doSomething() is executed the user submitted the form and started a new request.
So you should see "FETCH PARAMS" twice in the console because two Beans are created but for the second request id is null.
You can find a detailed explanation about the four JSF-Scopes here.
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.
Using JSF 2.0 and Spring, I use an #RequestScope managed bean. This bean stores information about the logged-in user. It loads the user from the DB in a #PostConstruct method:
#PostConstruct
public void init() {
String username = login.getUsername();
user = userDao.load(username);
}
The logged-in user can then trigger on action on the page that updates the user in database (using another managed bean).
However, the #RequestScope bean is constructed at the beginning of the request, which is before the call to the updating action. As a result, when the page is redisplayed, the User variable still has its old values.
My question is: do I have a way to run my loading method not at the beginning of the request, but after the request has been sent? Or am I dealing with this in the wrong way?
Thanks for your insight,
Sébastien
The logged-in user can then trigger on action on the page that updates the user in database (using another managed bean).
The same managed bean should have been updated at that point. If you can't reuse the same managed bean for some reason, then you should manually do it by accessing it in the action method and calling the setters yourself.
Update: based on the comments, here's how the beans should be declared and injected and used in your particular requirement:
#ManagedBean(name="#{login}")
#SessionScoped
public class LoginManager {
private String username;
// ...
}
#ManagedBean(name="#{user}")
#RequestScoped
public class UserManager {
#ManagedProperty(value="#{login}")
private LoginManager login;
private User current;
#PostConstruct
public void init() {
current = userDAO.find(login.getUsername());
}
// ...
}
#ManagedBean(name="#{profile}")
#RequestScoped
public class ProfileManager {
#ManagedProperty(value="#{user}")
private UserManager user;
public void save() {
userDAO.save(user.getCurrent());
}
// ...
}
<h:form>
<h:inputText value="#{user.current.firstname}" />
<h:inputText value="#{user.current.lastname}" />
<h:inputText value="#{user.current.birthdate}" />
...
<h:commandButton value="Save" action="#{profile.save}" />
</h:form>
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.