I was creating my first application using Apache wicket and am stuck on a problem. After the user logs in through the authentication method I have a new session which is created for that user. Now if I wanted to have data stored for just that user how would I use bean to implement that?
At the moment i created an interface and a class with get and set methods for the variables i wanted stored and created a bean such as <bean id="springApplicationContext" class="com..util.SpringApplicationContext"/> but what happens is the data gets overwritten but when i change the scope to "session" everyone has the same data in the bean still.
Thanks
The correct way is to use Session scoped Spring bean. There must be some error in your config if the data is visible to all users.
Using Spring has nothing to do with Wicket though!
Alternative approach is to store your data in Wicket's Session class.
Override MyApplication#newSession() method and return MySession class. The instance of MySession will be stored as an attribute in the HTTP session by Wicket. You can put any member fields inside MySession, e.g.;
public class MySession extends WebSession {
...
private MyBean myBean;
// setter and getter
...
}
Then in your Wicket code use it with: MySession.get().getMyBean().setSome(thing);
Related
I have a question that, i have a spring-mvc based project which is accessible by multiple user. My question is that when more than one user access that application then for each user there is separate controller class object or all user access the same controller class object.
There will be multiple controller instances for different requests.
Please read:
http://docs.spring.io/spring-framework/docs/2.5.x/reference/mvc.html
Related answer:
How does Spring MVC handle multiple users
If the controller is a bean (which is the usual case) then the default is one bean per Spring container context.
If you set the controller/bean to scope=prototype then you would get a new instance from the factory each time.
I have the following session scoped bean:
#ManagedBean
#Component
#Scope(proxyMode= ScopedProxyMode.TARGET_CLASS, value="session")
public class SessionData implements Serializable {}
and I store tomcat sessions in a database. The problem is that, when the application tries to deserialize a stored session, I receive the following error:
org.apache.catalina.session.PersistentManagerBase.swapIn Error deserializing Session EE913D2ACAD49EB55EDA657A54DFA2CB: {1}
java.lang.ClassNotFoundException: de.myproject.SessionData$$EnhancerBySpringCGLIB$$768b59b9
It seems that it serialized actually the whole Spring context, and obviously there is no such class de.myproject.SessionData$$EnhancerBySpringCGLIB$$768b59b9 after server restarts, so I receive the aforementioned exception.
Is there a way to avoid this, so that the session-scoped bean is serialized properly?
UPDATE: There is an issue regards this which marked as resolved without comments, however I still face it.
Please have a try:
using: import org.springframework.test.util.AopTestUtils;
Serializable readyToSerialize = AopTestUtils.getUltimateTargetObject(yourInstance);
before serialize it.
Note: this code is usefull to understund the problem, if this work, you have to analyze the project architecture and dependecies, to better accomplish for production code. First of all, why you need to serialize a ScopedProxyMode.TARGET_CLASS
Having a bean with a scope session doesn't mean that the bean is serializable and that it can be stored in a session.
As you can guess from the name of the class, a proxy class is generated at runtime with a different name at each startup. This explains why a problem occurs at deserialization.
I guess you try to add this SessionData as an attribute of the web session. You should not. Store your POJO data in the web session without using beans.
If you use the bean to inject database connections or similar objects, forget it. You can just use session scope beans for particular contexts which don't feet your requirements I guess.
i don't know well the your task, but in my opinion a data object like this should not be a spring bean because spring bean should be business logic bean, controller bean and so on and not session dto.
for this reason i consider thag you should try to think why you want store the data of your spring bean, and try to decopled the data that you want in http session, #sessionattribute of springmvc,from the business logic bean that shoud nor be session aware.
i hooe that this can help you to change your implementation stategy in order to find the solution of your problem
I am trying to figure out a solution for a small problem I have encountered whilst developing a small application. I am trying to pass an object created within one backing-bean and then later using that same object I created within another backing-bean. However, I would not like to make these backing-beans #SessionScoped, and preferably not use the #ManagedBean as I am using CDIfor my JavaEE application.
Is there anyway I could do this using CDI annotations and injecting one backing-bean to another and then have the ability to access that object previously created?
As an example, refer to the below beans:
#Named
#ViewScoped
public RegisterController implements Serializable {
User user = new User();
// Getter and Setter methods which are populated by the JSF page
}
Get Object User created within the above bean and use it within the controller below:
#Named
#ViewScoped
public PaymentController implements Serializable {
#Inject RegisterController registerController; // Injecting bean
registerController.getUser().getName(); //this is null when I try access the properties of the object 'User'. I am assuming this is because #ViewScoped annotated on the 'RegisterController' class?
// I would like to use the User object created in 'RegisterController' here an access properties etc...
}
Could I use the #Inject annotation offered by the CDI?
UPDATE
Ok, so I have got the above working when I annotate the RegisterController with the SessionScoped annotation, however I do not want this Bean annotated SessionScoped as I will probably run into further implications down the track, such as pre-population of fields, etc... Any ideas how to implement this any other way?
Well, #ViewScoped is too short to the purpose and #SessionScoped is too long. Then why not use #ConversationScoped?
See here.
you can use in RegistrationController:
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("user", user);
and in PaymentController:
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user");
this is very useful, you can save the objects you want in the map.
I am coming to Java from Rails and PHP, so my thinking here may be tainted.
I would like to implement a login system similar to ones I have done in my other systems (I understand you can manage login etc using the built in properties of Java EE, I just want to understand how I could do this manually and share objects amongst beans.)
With rails or php it is easy to maintain a session variable that holds the id of a logged in user. Then a global variable in PHP, or a property on the applicationController in rails can be pre-loaded with the user object, enabling it be available in all controllers/pages. That way the logged in status of the user and other parameters are easily accessible to all pages/controllers.
I don't know how to do a similar thing using JSF.
I know how to build a user object using JPA, and then create a managed bean with session scope that holds a reference to the user object after logging in using a loggin method from a login form. That part I understand:
#ManagedBean
#SessionScope
public class LogginController {
// inject persistence context, or use EJB to do actual loading etc
private User currentUser; //JPA Entity
void loginAction() {
// action from login form
// authenticates user and loads user object into currentUser property
Where I get stuck, is that although the managed bean that contains the currentUser property has session scope, how would I access that property in other managed beans to get the current user? Managed beans seem to exist in isolation from each other.
Is the following code acceptable?
#ManagedBean
public class SomeOtherBean {
#ManagedProperty
LoginController loginController;
public void someOtherMethod() {
User myUser = loginController.getCurrentUser();
//
// etc
Would the class having the bean injected also have to have SessionScope too?
Is this the wrong approach, would I need to manually set the session using the underlying ServletContext so that the user was accessible in other beans (i.e. save the id of the logged in user in the session, and then reload the user after accessing the user id session variable in different beans)?
Am I going about this all wrong? Is there an easier way I am missing.
Is the following code acceptable?
Yes (assuming that it's pseudo; in real code it should be a private property and you should specify the managed property value like so #ManagedProperty("#{loginController}") and provide at least a setter method).
Would the class having the bean injected also have to have SessionScope too?
Not necessarily. It can perfectly be a request or view scoped bean, but not an application scoped bean (it would result in an exception). At least, you should be very careful with choosing the bean scope. Do not choose a too broad scope for the data it holds. See also How to choose the right bean scope?.
#Autowired works only once.
What to do to make it wire the bean every time the Servlet is recreated?
My web-app (Tomcat6 container) consists of 2 Servlets. Every servlet has private fields.
Their setters are marked with #Autowired
In the init method I use
WebApplicationContextUtils
...
autowireBean(this);
It autowires the properties marked with #Autowired once - during the initialization of the Servlet.
Any other session will see these fields values, they will not be rewired after the previous session is destroyed.
What to do to make them rewire them each time a Servlet constructor is called?
a) Put the autowiring into the constructor?
Or better 2) get a web app context and extract a bean from there?
There seems to be some misunderstanding about how the container works. Servlets are essentially singletons, you don't get a new servlet everytime someone calls the server. Storing state in private fields on a servlet is pretty much an error.
What is the scope and life-cycle of the stateful part of your request processing? If it's just the life of the request then you can take whatever on your servlet is stateful and move it into another class. Then you can define a prototype bean for that class and use getBean at the start of the request to get a new one. If you want to start getting fancy you could write a filter that puts a new bean into a ThreadLocal at the start of each request.
If your state needs to span multiple requests, you need to start keeping state or a key that points to the state storage on the web session, or look into using a conversation framework.
Try using scope as prototype for that bean #Scope("prototype")
You may try to use #Scope("session")