session is getting reset in IBM Websphere Commerce - websphere

I am setting a session in the jsp using scriplet in IBM WCS and setting a value here but when reloading the page the session value is getting lost .
here is how I am setting session attribute
<%
session.setAttribute("testMap", testValue);
%>
However on my local toolkit Its works fine ,but when it is deployed to server having this issue
Please suggest any solution regarding this
Thanks
Ankit

Session state in Websphere Commerce is saved in the Business Context, which is tied to the users ActivityToken.
Session state is serialized to the database, and will be available if the users session goes to another server in the cluster.
You can add your own session state by registering a new context element in BusinessContext.xml in the WC\xml\config\BusinessContext.xml, like so:
<BusinessContext ctxId="MyContext"
factoryClassname="com.ibm.commerce.context.factory.SimpleBusinessContextFactory" >
<parameter name="spiClassname" value="com.myorg.commerce.context.contentimpl.MyContextImpl" />
Then you need to tell which kinds of sessions your Context will be present in
<!-- web site store front configuration -->
<InitialBusinessContextSet ctxSetId="Store" >
...
<InitialBusinessContext ctxId="MyContext" createOrder="0" />
The context will be created along with all other contexts, and will be serialized to either the CTXDATA database table (for known users) and in a browser cookie for anonymous users.
Your context class should look something like this:
An interface class com.myorg.commerce.context.mycontextimpl.MyContext
public abstract interface MyContext extends Context
{
public static final String CONTEXT_NAME = "com.myorg.commerce.context.mycontextimpl.MyContext";
public abstract String getSomeValue();
public abstract void setSomeValue(String v);
}
And an implementation
public class MyContextImpl extends AbstractContextImpl
implements MyContext
{
}
After setting a new value, use "this.setDirty(true)" to flag the changes for persistance.
You must also override getContextAttributes to return the values of your context that needs to be serialized, and the setContextAttributes to re-establish the values.
The point is, that the context does more than simply store values. You put invariants in the context, that should hold true for all aspects of the users interaction with the site. The best example is the EntitlementContext, which holds which contract(s) you are buying under, which can be rather complicated to calculate.
Anyway, to access your context from a command, you'd use
this.getCommandContext().getContext(MyContext.CONTEXT_NAME);
And from a jsp
if (request.getAttribute("myContext") == null) {
request.setAttribute("myContext", ((CommandContext) request.getAttribute("CommandContext")).getContext(MyContext.CONTEXT_NAME));
}
after which you can use it as
${myContext.someValue}

The short answer is don't do this. WebSphere commerce is typically deployed in a distributed environment, and you might be seeing the effect of this when your code gets deployed. It is a lot of work for the application to persist the session across WebSphere nodes. Instead use a cookie, or create a database table. What are you trying to store in that map that has to be in session.

Related

How to pass data from page to page in Thymeleaf based spring boot application

I am developing application in Spring boot and i am using Thymeleaf as a template engine. Its like a Ordering application where user selects option on Page 1, Page 2 and so on and at last page i have to save all the previously user selected options to DB.
Can anyone suggest what will be the best design approach to pass data from one page to another should i need to use session ? I have Model objects defined for each page and i am passing to and from data using these model object .
I'd recommend completing this short tutorial (https://spring.io/guides/gs/handling-form-submission/). It illustrates how model attributes can be sent from a client page to the server as well as from the server to the client page.
Once the model is populated to its final state, the model can correspond to a table in your database as is illustrated in this tutorial (https://spring.io/guides/gs/accessing-data-mysql/) via Hibernate and the #Entity class.
Cheers!
I did something like below
#Component
#Scope("session")
public class Cart
{
// simple POJO fields
}
and then use this inside the Controller i want
#Scope("request")
public class SessionController
{
#Autowired
private Cart cart;
#RequestMapping("/addToCart")
public String addToCart(#RequestParam("id") int id)
{
//
}
}
since the scope of cart is session so i can use this model object to whichever controller i want put the value in cart object get the value from it wherever i want.
Sessions work great as well. Cheers!

Store data not in database

I want to implement simple chat but store them only during server work. I don't want to store them in database, just like in List or Map. How to?
This solution works for "Simple" chat as you explained.
There isn't much information on how you had built this before so I'm just going to explain how to have an Application scoped bean that can be injected into other beans to handle storing chat.
You can configure a Service to store this information.
ChatHistoryService.java
#Service
#Scope("application")//This is the key this will keep the chatHistory alive for the length of the running application(As long as you don't have multiple instances deployed(But as you said it's simple so it shouldn't)
public class ChatHistoryService {
List<String> chatHistory = new LinkedList<>();//Use LinkedList to maintain order of input
public void storeChatMessage(String chatString) {
chatHistory.add(chatString);
}
public List<String> getChatHistory() {
//I would highly suggest creating a defensive copy of the chat here so it can't be modified.
return Collections.unmodifiableList(chatHistory);
}
}
YourChatController.java
#Controller
public class YourChatController {
#Autowired
ChatHistoryService historyService;
...I'm assuming you already have chat logic but you aren't storing the chat here is where that would go
...When chat comes in call historyService.storeChatMessage(chatMessage);
...When you want your chat call historyService.getChatHistory();
}
Once again keep in mind that this really only works for a simple application. If it's distributed there will be different chat histories per instance of the application at that point you could look into a distributed cache.
In any case don't go beyond simple with this implementation.
If you look here it will give you an idea of several caches that work with spring boot.
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache

how to share the token between classes

I have having a design issue with asp.net web-api and would like to know how to solve this problem
public abstract class BaseApiController<TEntity> : ApiController where TEntity : Entity
{
protected string GetUsername()
{
return Utilities.GetUsername(Request.Headers.Authorization);
}
//some other code
}
public class StakeholderApiController : BaseApiController<Stakeholders>
{
ILogger _logger = new CustomApiLogger("StkhManager", GetUsername())
//some other code
}
now the problem I have is:
I have the BaseApiController which I am using the share certain functionality between all ApiControllers.
And then I have some specified ApiController for certain not shared functionality.
Now while doing logging, I do want to log the logged in user's name, the problem is I have to pass it everytime I create a new instance, is there a way I can make the logged in user's name global for the current api request so that it can be accessed everywhere.
I cannot make it static, otherwise for others request it will give wrong username.
is there a way I can avoid passing it everytime. Given that webapi is stateless, so session cant be used, is there anyother way??
I am using angularjs front end, hence I am NOT using any authorization technique provided by MVC/.net
Note:
I cannot move creation of Logger to base class for certain reasons
This is just one example, I want to use the logged in user's name in many other place. Hence dont want to pass it around.
There is a standard pattern in setting and accessing principal with ASP.NET Web API. From an ApiController such as your BaseApiController, you can just use the User property to retrieve the same. To set it, typically, the HttpRequestContext is obtained from the request object and the principal is set like so.
Request.GetRequestContext().Principal = new ClaimsPrincipal(...);
BTW, you can access the current request object in the Web API pipeline pretty much from anywhere.

Storing session data in controller

I'm new to Spring. I'm working on a MVC application that would works as follows:
1) user fills the form with data necessary to create the connection to some service
2) controller gets the data from input, create new object serviceManager and save this object e.g in some HashMap with serviceId
3) next time user wants to use this service, controller using serviceId reads data from HashMap.
So I simply need to store this HashMap throughout the whole session in my controller for future use. What would be the best way to accomplish that? Maybe creating serviceManager object each time and reading data from database is the proper solution? In my controller I'm already using #Autowired fields which perfectly serve the purpose, but they're defined in spring xml and I have to store the data dynamically.
Seems your requirement is kind of same with mine which I should keep the main data in the session and every time get the detail data from client and combine 2 kind of data to retrieve something from database. I just put the main part data in the session and then in the whole session that I can get it. I also try to use #SessionAttribute, but after tried dozens of time, I gave it up, it has a lots of problems. So if you can, I just recomment you to store the data in session, that's the samplest way.
I'm newish to spring myself, but as far as putting this in the session:
#Controller
#SessionAttributes({"myObject"})
public class MyController() {
...
#RequestMapping(value="/foo")
// Corrected as per Costi below
// public String someMethod(#PathVariable MyObject myObject) {
public String someMethod(#ModelAttribute MyObject myObject) {
...
}
}
#SessionAttributes will put a MyObject named myObject into the session, if it's not already there, and the #PathVariable pulls it down so you can use it in the method.
The curlys in session attributes aren't necessary for just one attribute, however, you can specify more than one, comma separated, when you use the array notation (which is to say: the curlys)

NHIbernate SessionFactory and Configuration Recreation

I have one difficult situation.
As we know NH SessionFactory is a singleton in our app.
"Heavyweight, thread-safe, and you only should ever have one per
database".
And SessionFactory is created from Configuration().BuildSessionFactory() where Configuration() is my fluently configured database.
Here is the poblem.
I need to use different users for my connection string in an MVC app. This is needed to connect to the database by different users. When connection is ok, then I use NH to manipulate domain mapped objects.
Question here is how to pass different users to Configuration and use this SessionFactory in case when we need create Configuration first of all? Creating the SessionFactory again is a wrong way, right?
And this becomes more harder because I use Windsor container to register all objects before my MVC app's run.
It sounds like you are wanting to provide a different connection string for different users of your application.
NHibernate has a feature in which you can provide your own DriverConnectionProvider which will allow you to ultimately be able to create custom connection strings on the fly by overriding the GetConnection() method.
Example:
class DynamicConnectionProvider : DriverConnectionProvider
{
public override IDbConnection GetConnection()
{
IDbConnection connection = Driver.CreateConnection();
try
{
connection.ConnectionString = // Add your logic for dynamically creating a connection string
connection.Open();
}
catch ( Exception e )
{
connection.Dispose();
throw;
}
return connection;
}
}
You can also take a look at the following links for examples:
https://stackoverflow.com/a/2927967/670028
http://nhforge.org/blogs/nhibernate/archive/2008/09/18/extending-nhibernate-s-driverconnectionprovider.aspx
And yes, creating duplicate SessionFactories would be quite costly to your applications memory usage, would complicate your applications architecture, and is really unnecessary as there are other options such as the one I listed above.

Resources