My problem is te data is not refresh in the datatable. I want to destroy the session scoped when I clicked to the item in the menu.I know that it's possible with Viewscoped but I want to learn other way.
Thank in advanced.
Controller:
#ManagedBean
#SessionScoped
public class MyController implements Serializable {
//getters and setters
...........
}
Menu:
<td><h:outputLink styleClass="itemOutputLink" value="# {request.contextPath}/pages/page.faces">Page1</h:outputLink></td>`
There is no really "clean" way of doing that. A #SessionScoped bean should live as long as a Session. Thus I emphasize again that you should better adjust the beans scope.
But if you really still need to do it, the easiest way would be to do it like this:
public static void removeSessionScopedBean(String beanName)
{
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(beanName);
}
For #ViewScoped beans you could do it this way:
public static void removeViewScopedBean(String beanName)
{
FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove(beanName);
}
Related
I store a file into this bean via primefaces fileUpload
#ManagedBean(name = "uploadController")
class UploadController{
private UploadedFile uploadedFile;
public void handleFileUpload(FileUploadEvent event) {
setUploadedFile(event.getFile());
}
//getter&setter
Is it possible to access to the field uploadedFile into another bean such as
#SessionScoped
public class BrandController implements Serializable {
private UploadedFile logo;
//getter&setter
and link them in a certain way?
I tried this :
#ManagedProperty(value = "#{uploadController.uploadedFile}")
private UploadedFile logo;
But debugging shows that logo is null when I attempt to use methods on it. Thanks for your help.
I think I was using wrong the ManagedProperty.
#ManagedBean(name = "uploadController")
public class UploadController {
#ManagedProperty(value = "#{brandController}")
private BrandController brandController;
public void handleFileUpload(FileUploadEvent event) {
brandController.setLogo(event.getFile());
}
You should read this awesome answer about jsf scopes.
How to choose the right bean scope?
Session and Application scopes allows you to use beans beyond the interaction of the jsf page associated with it, however this could cause you encountered this bean in other places in "unespected" state.
For what has been said previously, for this purposes i used the flash scope, witch is a short living scope, how does it explain in above StackOverflow link as well as in the following:
Pass an object between #ViewScoped beans without using GET params
I am new to jsf and using JSF 2.0 to keep user information in a session scoped bean. I need to access this information across other beans for grunt work. Presently, this is how i am doing:-
private UserBean myuser1 = (UserBean)FacesUtils.getManagedBean("UserBean");
and then access properties as
if (myuser1.getUserType == 1) ...
this works but some time throws Argument Error: parameter key is null exception. I have been using following method too:-
private UserBean myuser2 = new UserBean();
if (myuser2.getUserType == 1) ...
In second method, my understanding is that if UserBean is already created in session, it would be retried. There are lots of question about 'how to access one bean in another' so i am confused. Please tell me one clean method which should always work and not throw null pointer exception abruptly.
The simplest way I know of is using #ManagedProperty, I don't know what you mean by safest though.
Let's say this is your sessionScoped bean :
#ManagedBean
#SessionScopped
public class UserBean {
//bean attributes and methods
}
Then you can access it in any other bean (provided it has the same or a narrower scope) as an attribute like this :
#ManagedBean
#ViewScoped //in this cas you can use SessionScoped, FlowScoped, or RequestScoped too
public class AnotherBean {
#ManagedProperty("#{userBean}")
UserBean userB;
//rest of the bean
//be sure to add getters and setters for the injected bean
}
For more details check this
Hope this helps.
Actually,
parameter key is null exception: it's either you didn't initialize the object witch can be solver with either adding
object = new Object(); // in the constructor of the class.
The second problem may be that the object is " DETACHED " you need to call the object using the method merge (with the entity manager).
A detached object is a known value but the JPA system doesn't know if it is the latest version from the DB or even sometimes the id value is not set for some reason (Not managed with jpa in other words it can be your case).
If em is your entity manager and you have the following function:
public Object latestVersion(Object o){ em.merge; }
In your Bean with:
#EJB
Service service;
if you do em.latestVersion(o); the problem of detached object is solved.
And for the real answer:
To access a object from another view you can simply do the following.
#ManagedBean
#SessionScoped
..... Bean1 {
public static Object o;
.....
}
#ManagedBean
..... Bean 2 {
private Object b=Bean1.o;
.....
}
Good luck
The standard practice of setting dependency of a scoped bean in another scoped bean is to use #Inject annotation like
#Inject UserBean userBean; in the bean you want use the UserBean object.
Your UserBean should be a stateful one.
#Stateful
#LocalBean
public class UserBean
{
private String name;
public String getName() { return name; }
public void setName( String name_ ) { name = name_; }
}
And just inject it into a stateless bean to modify its state:
#Stateless
#LocalBean
public class MyStatelessBean
{
#EJB
private UserBean userBean;
public String getUserName() { userBean.getName(); };
public void setUserName( String name_ ) { userBean.setName( name_); }
}
Or you can access it from (not wider scoped) managed beans as well in the same way:
#ManagedBean
#Dependent
public class MyJSFManagedBean
{
#EJB
private UserBean userBean;
}
You wrote in your comment you does not use EJBs at all. The picture modify like this:
The UserBean should be a SessionScoped CDI bean
#Named
#SessionScoped
pubilc class UserBean
{}
The othe CDI bean should be in a nearer scope:
#Named
#Request // or #ViewScoped or #Dependent
public class OwnerBean
{
#Inject
UserBean userBean;
}
The container automatically takes care to create the beans in the right scope and insert them into the owers (any kind of container managed objects : servlets, filters, action listeners, JSF/CDI beans). You need to insert a wider scoped resource into a thinner scoped one.
I'm probably really close to the solution but I'm new with JSF and I don't see my mistake.
I have a first SessionScoped Managed Bean that represents Business information (address, website, ...)
#Named(value = "businessController")
#SessionScoped
public class BusinessController implements Serializable {
private Business current;
#EJB private BusinessFacade ejbFacade;
....
I have a second SessionScoped Managed Bean that represents the logged in user
#Named(value = "loginController")
#SessionScoped
public class LoginController implements Serializable {
private Login current;
#EJB
private LoginFacade ejbFacade;
#ManagedProperty(value="#{businessController}")
private BusinessController businessController;
public BusinessController getBusinessController() {
return businessController;
}
public void setBusinessController(BusinessController businessController) {
this.businessController = businessController;
}
When a user logs in, I set the current attribute from the loginController
Depending on this current user, I want to set the business attribute from the businessController :
businessController.setCurrent(current.getBusiness());
My problem is that the businessController attribute is null !
I use NetBeans 7.0.1 and GlassFish 3.1
In debug mode, I can see a viewId variable with the value
>No current context (stack frame)<
Unfortunately it doesn't ring any bell to me.
Any help would be appreciated
Thanks
You are mixing JSF managed beans with CDI managed beans.
Your BusinessController is annotated with the CDI annotaion #Named but gets injected with the #ManagedProperty annotation (from JSF). CDI managed beans need to be injected with #Inject. No getter or setter needed in this case. If you tend to use CDI, make sure that you import the correct #SessionScoped:
CDI: javax.enterprise.context.SessionScoped
JSF: javax.faces.bean.SessionScoped
Try the following (After making sure to have the correct scope class imported):
#Inject private BusinessController businessController;
I'm trying to wrap my head around some basic JSF 2 concepts. For instance, if I have a managed bean, Bean1:
#ManagedBean
public class Bean1 {
private String foo;
private String bar;
}
and the values for foo and bar are obtained from a JSF web form. On each submit of the web form, I want to store an instance of Bean1 in a Java Collection of another bean:
#ManagedBean
public class Bean2 {
private List<Bean1> beanList;
}
What is the correct way to achieve this? Thanks.
BalusC is 100% per cent right, but (as he warns) his answer will be useless. The important point here is that you do not need nor want the second bean to be managed at all. It is your model, not your GUI. You probably wanted something like:
#ManagedBean
#ViewScoped
class PeopleHolder {
private List<Person> people = new ArrayList<Person>();
// not managed at all:
private Person currentPerson;
// just the getter, no need for a setter
public Person getCurrentPerson() { return currentPerson; }
#PostConstruct
public init(){ currentPerson = new Person(); }
public void addCurrentPersonToList() {
people.add(currentPerson);
init();
}
// just for test:
public List<People> getPeople() { return people; }
}
and now a form:
<h:form>
<h:inputText value="#{peopleHolder.currentPerson.name}" />
<h:inputText value="#{peopleHolder.currentPerson.lastName}" />
<h:commandButton action="#{peopleHolder.addCurrentPersonToList}" />
</h:form>
Make Bean2 a managed property of Bean1 so that you have access to its beanList property.
#ManagedBean
public class Bean1 {
private String foo;
private String bar;
#ManagedProperty("#{bean2}")
private Bean2 bean2;
public void submit() {
bean2.getBeanList().add(this);
// ...
}
// ...
}
(please note that this way just the reference is stored, not a clone of the Bean1's state or something!)
Needless to say that this is a design smell. There are likely better ways to achieve the concrete functional requirement which you've had in mind while asking the question but didn't tell anything about. In the future try to ask how to solve the functional requirement instead of how to achieve a solution (which may not be the right solution after all).
I have a problem I don't understand: Behind any View I have a controller ManagedBean that is RequestScoped and a data ManagedBean, that holds the data for the view and is SessionScoped.
So there are two views, which are login with loginData and loginController and overview with overviewData and overviewController.
The functionality should be like that:
The User logs into the application (loginController method)
If Authentication is successfull, there is a redirect to overview.xhtml (again in loginController method)
Then the overviewData gets its data by the overviewController, which retrieves them from business logic layer
The overview.xhtml shows the retireved data
So, the point is that I want to fill overviewData out of loginController, right after login! (???or if possible right befor overview view is constructed, if possible???).
I tried it with managedProperties, but the one I initiate in loginController is a different object than the managedProperty in overviewController, although they have the same name! How is that possible.
Oh boy, I doubt you guys understand what I mean, so I need to post some code:
LoginController.java
...
#ManagedBean
#RequestScoped
public class LoginController {
#ManagedProperty(value = "#{overviewData}")
private OverviewData overviewData;
OverviewController overviewController;
public LoginController(){
overviewController = new OverviewController ();
}
String login() throws Exception {
UsernamePasswordToken token = new UsernamePasswordToken(loginData.getName(), loginData.getPw().trim());
try {
currentUser.login(token);
overviewController.fillProjects();
...
OverviewController.java
...
#ManagedBean
#RequestScoped
public class OverviewController {
#ManagedProperty(value = "#{overviewData}")
private OverviewData overviewData;
public void fillProjects(){
if(overviewData == null){
overviewData = new OverviewData();
}
overviewData.setProjects(projectService.getProjects()); //retrieves data from business logic
}
...
OverviewData.java
...
#ManagedBean(name = "overviewData")
#SessionScoped
public class OverviewData {
private List<ProjectDTO> projects; //that's what the view needs to display the overview
public void setProjects(List<ProjectDTO> projects) {
this.projects = projects;
}
...
I hope that helps to show my problem, if you don't understand it, pls ask in a comment..
Would be nice if you can help me :-)
Cheers...
You're creating beans yourself using new instead of letting JSF do the job.
overviewController = new OverviewController ();
and
overviewData = new OverviewData();
This is wrong. JSF won't utilize any beans which you've created yourself this way. Remove those lines and add another #ManagedProperty on overviewController inside LoginController (and make the property private).
#ManagedProperty(value="#{overviewController}")
private OverviewController overviewController;
JSF will create the bean itself and set it as managed property directly after parent bean's construction. You just have to access it the usual Java way (without the need for nullchecks).