Can I rewrite the session attribute WW_TRANS_I18N_LOCALE in Struts2? I want to set locale in cookies, for future use, because by default session have a timeout of 30 minutes, this is to small amount of time for the locale, if user isn't using the site. I am trying to set WW_TRANS_I18N_LOCALE depending on cookies value, but without any luck, the value remains the same as it is.
I found here a question like mine, but all of my jsp's pass through Actions https://stackoverflow.com/questions/5291271/struts-2-internationalisation-problem , and this is not a solution ..
So you want to change a session value in an action? I'm not clear on the last line, but just implement SessionAware then it should be straight forward. The best place to set the value would probably where ever the user logs in (if any).
Something like...
import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
public class MyAction extends ActionSupport implements SessionAware{
Map<String, Object> session;
#Override
public String execute(){
session.put("WW_TRANS_I18N_LOCALE", "fr");
return SUCCESS;
}
#Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
}
should do. There are aware interfaces for most other scopes see the top of this page: http://struts.apache.org/2.0.11/struts2-core/apidocs/org/apache/struts2/interceptor/package-summary.html
Edit:
Thinking about this I can't recommend using cookies to store the language preferences. But if you were to do this... the default i18n interceptor will check if a parameter called "request_locale" exists and set the value on the session to that value. You don't want a value stored on the session. But since this is how struts2 handles this by default you could do something like the following:
create your own i18n interceptor which is a copy of the existing but removes the language data saved into the session (thus the value pushed into the session, really only exists for the request duration).
create a javascript function which is added to every page (probably through some template system), which after the page has loaded looks for all anchor tags and form tags. In the case of anchor tags is adds the "request_local" parameter to the end from the value that it finds in your cookie, and it will add a hidden field to every form which will also set the "request_local" parameter from the cookie.
I'd probably put a language selection drop down on every page too, which sets the cookie value and then would reload the current page. For an idea of creating such a list (although a drop down would be better than links): Tiles2 Struts Switch Locale
For information on the i18n interceptor: http://struts.apache.org/2.1.2/struts2-core/apidocs/com/opensymphony/xwork2/interceptor/I18nInterceptor.html
For the JS function, since I'm partial to jQuery I'd start with either this: http://plugins.jquery.com/project/jsper
or this...
http://plugins.jquery.com/project/Cookie
Related
I am writing an application in which on first page select city after this on every request data will come for only for selected city. How can we persist this without authentication or I have to pass this in URL every time.
I am using spring boot and Thymeleaf.
you can use session to store it, in spring MVC there is #SessionAttributes you can use it inside your controller, here am expecting that you are use "city" as name for your attribute.
#Controller
#RequestMapping("/")
#SessionAttributes("city")
public class EditCityForm {
// ...
}
You have various options.
The first and obvious is to pass the city on every request as you point. But this can be painful.
A second option is to store this value in session so you can get this value every time you need it. But be careful handling it, do not forget to update it when its necesary etc.
with Spring MVC you can store data in session in your controller doing this:
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
Session session = attr.getRequest().getSession();
session.setAttribute("city", cityName);
To recover data from session
session.getAttribute("city");
Even if you do not use SpringMVC you can get the session from HttpRequest, is much more standard, but only avaliable when you have access to HttpRequest object:
Session session = request.getSession();
session.setAttribute("city", cityName);
Spring MVC 4.1
Hi,
I have a situation where, on a single page, there are several input fields. As the users enters numbers into these fields, a bunch of calculations will occur and update various other fields on the page.
I want this whole calculation model to take place in Java on the server-side. I really want to avoid replicating this logic in Javascript on the client.
What I envision is...
User opens the page, the object that does the calculations (let's call it Calculator) is created and its initial state is set (many of its fields are pre-populated with values).
This Calculator instance is stored and available for the duration of the user's time on that page.
Whenever the user changes a value in an input field, that new value is sent to the server via ajax and plugged into our Calculator object. The Calculator, re-calculates the other fields based on the new state and returns the results to the page.
The other fields on the page are updated accordingly.
The key here is that I'm not sending the state of all fields with each ajax request. I'm only sending the current value that was updated. Essentially, I'm trying to ensure that the form state and the Calculator state on the back-end are always synchronized.
I have looked into #SessionAttributes and #ModelAttribute.
The problem with #ModelAttribute, as I understand it, is that it will be re-created with each ajax request.
The problem with #SessionAttributes is that it is a session variable. What if the user has two of these windows open? And how do I ensure the object is removed from the session when they leave the page? etc...
Maybe there's no magic Spring bullet and I just have to figure out the session variable thing. But any pointers on dealing with this would be much appreciated.
Thanks!
You have a couple of options:
.1. Like you have said using the #SessionAttributes, however yes it suffers from the issue that you have mentioned, multiple instances of the same session will see the same variable.
.2. Store state somewhere else and re-hydrate the state using #ModelAttribute annotated method. I would personally prefer this approach, essentially when you create the form, create it with a identifier for the current state:
#RequestMapping(params = "form")
public String createForm(Model uiModel) {
uiModel.addAttribute("calculationId", UUID.randomUUID().toString());
return "calculationpage/create";
}
Then for subsequent ajax requests, ensure your previous calculationId is sent across:
#ModelAttribute("calculationState")
public CalculationState rehydrateState(String calculationId) {
//retrieve current state of calculation from some persistent store..
}
#RequestMapping("/calculate")
public String handleCalculation(#ModelAttribute("calculationState") CalculationState c) {
//you will get a calculationstate with the delta's at this point..
}
.3. Another potential approach may be to use session but disambiguate different instances within the session with a custom id:
public String handleCalculation(HttpSession session, #RequestParam("calcId") String calcId) {
CalculationState calcState = (CalculationState) session.getAttribute("calculation" + calcId);
}
You need any sort of persistent store outside session to store and retrieve the state of your calculator model. Like Biju said, I will go for solutions like No 2.
I've been struggling with passing some value between controller.
I have one controller like this:
#RequestMapping(value = "/add", method = RequestMethod.GET)
public String addGet(HttpServletRequest request, #ModelAttribute(value="branch") Branch branch, Model model, blahblahblah)
//What I want to pass and re use:
String loadRespond;
try{
loadRespond= *SOME LOAD STRING METHOD*;
branch= branchManager.convertString(loadRespond); //METHOD TO SPLIT STRING & INDUCT TO OBJECT
}catch{exception){
//blabla
}
After I successfully inducted all the attributes into the object branch,i show them all through a binding form. What i want to do is, when i'm going to update the data/change some attribute, i want to compare the old branch to the new changed branch. This means that i have to pass the old branch object or the loadRespond string onto the POST method so that can be used. Do anyone have any idea of how to do this? Maybe to assign it to hidden type field in the jsp? and then use it on the controller with request mapping /add of method type post? Thanks..I'm a newbie..
Why don't you try out with session scope ?
store your old branch into the session . and when you get the new object compare with the old one (by retrieving from session)
You can save into session as any of both,
request.getSession().setAttribute("sessionvar", "session value");
#SessionAttributes("sessionvar")
A nice Example here to start with it.
Side-note : your question title doesnt quite expalain your problem and the solutions may vary
As San Krish notes in his answer the most common way is to use #SessionAttributes and pass objects/data using them.
This is useful if you don't worry about user moving backwards and forwards in a page, or want basic control of the object.
Now if you want to have a chain where controller 1 passes to controller 2 which may pass to controller 3 your best bet is to implement web flows.
Summary:
For short and sweet and quick: SessionAttributes is the way to go, example here http://www.intertech.com/Blog/understanding-spring-mvc-model-and-session-attributes/
For chain passing, greater control and validation use Spring Web Flows.
I have the need to pass a URL to Magento, where it should redirect the User after completing the logout. To store it, I do the following:
$BackTo = Mage::app()->getRequest()->getParam('backto');
if(!empty($BackTo)) {
Mage::getSingleton('core/session')->setBackTo($BackTo);
}
When needed, I retrieve the URL using Mage::getSingleton('core/session')->getBackTo(). The issue is that, while this works well on login, it doesn't work on logout (where it's most needed). I can store the session variable, I can also immediately retrieve it, but, when I am in logout.phtml, where the redirect JavaScript is located, such variable is set to null.
I suspect that the redirect performed by Magento upon logout has something to do with this "disappearing" session variable, but I can't say for sure.
For completeness, here is the relevant code (there's more code than this, but they are mainly auxiliary functions, which don't get called on logout).
Account Controller
class MyPackage_Redirectplugin_AccountController extends Mage_Customer_AccountController {
/**
* #see AccountController:logoutAction()
*/
public function logoutAction() {
$this->_getSession()
->logout()
->setBeforeAuthUrl(Mage::getUrl());
// Store the "back to" URL in a session variable
$this->StoreBackToURL();
$this->_redirect('*/*/logoutSuccess');
}
protected function StoreBackToURL() {
// Store the value of the "backto" argument, if it was passed
$BackTo = Mage::app()->getRequest()->getParam('backto');
if(!empty($BackTo)) {
Mage::getSingleton('core/session')->setBackTo($BackTo);
// At this point I can see the correct value stored in the session variable
}
}
}
Logout.phtml
// The following command returns null
$redirectURL = Mage::getSingleton('core/session')->getBackTo();
Thanks in advance for the help.
Update 12/09/25 - Found a workaround
Since I couldn't find a way to pass a session variable to the logout page opened by redirect, I chose an alternative way: I'm passing it via the URL. Specifically, I implemented a logoutAction() which calls $this->_redirect('*/*/logoutSuccess', array('myvar' => $MyValue));.
In the template, where I have to do the redirect, I simply read such parameter using Mage::helper('core')->urlDecode(Mage::app()->getRequest()->getParam('myvar'));.
I'm aware that there might have been better ways to implement the whole thing, but I needed a bug fix solution and this does the job. Thanks to all people who answered.
The cleanest option which I see (no controller rewrite necessary!) is to observe the dynamically-dispatched controller_action_postdispatch_customer_account_logout event - see the relevant line fromMage_Core_Controller_Varien_Action::postDispatch(). The postDispatch() method is called after the controller action completes.
Example observer method:
public function logoutRedirect($obs)
{
$redirectUrl = Mage::getUrl(/* url args */);
$obs->getControllerAction()->getResponse()->setRedirect($redirectUrl);
}
Doing this will redirect the user to the desired URL directly upon logout meaning that the logoutSuccess page with the JS redirect will not be accessed.
If the desire is to have the logoutSuccess page render as normal, but redirect to a different URL, this can be achieved a couple of ways:
1. By creating a custom template
2. By creating a custom template block class, overriding the getUrl() method to retrieve the URL of your choice, and assigning that as block to render in the content area (by removing or displacing the customer_logout block) in a custom layout XML update file.
just observe this event customer_logout, and when event call method you save the session key on database.
Learn more: http://www.magentocommerce.com/wiki/5_-_modules_and_development/reference/events
http://www.magentocommerce.com/wiki/5_-_modules_and_development/0_-_module_development_in_magento/customizing_magento_using_event-observer_method
GL.
Update 12/09/25 - Found a workaround
This workaround has also been posted in the question itself.
Since I couldn't find a way to pass a session variable to the logout page opened by redirect, I chose an alternative way: I'm passing it via the URL. Specifically, I implemented a logoutAction() which calls $this->_redirect('*/*/logoutSuccess', array('myvar' => $MyValue));.
In the template, where I have to do the redirect, I simply read such parameter using Mage::helper('core')->urlDecode(Mage::app()->getRequest()->getParam('myvar'));.
I'm aware that there might have been better ways to implement the whole thing, but I needed a bug fix solution and this does the job. Thanks to all people who answered.
I want to be able to read / write some variables to the current session in my Salesforce site pages.
I have a site built using Salesforce Sites, I need to store/retrieve some values across all the pages (consider that I am building something similar to a shopping cart).
However I cant find any good example on how to read and write variables to the session (anonymous user).
I am using Visualforce pages with several controllers built in Apex.
Regards
If you are building something like a shopping cart, or a "wizard" where you need to keep controller variables in context from one page view to another, then the best way to do this in VisualForce is to use the same controller.
When the user submits a form ( through actionFunctions, commandButtons, or commandLinks, etc.), and your controller returns a page Reference, the view state is preserved if the new visual force page uses the same controller.
In this way, you could, for example, have the user enter their name and email address using apex:inputField tags on page one. They navigate to page two, which uses the same controller as page one, and the page could reference the same controller variables. Essentially, the controller is still in scope, and so are all the variables that were updates.
Example:
Page one:
<apex:page controller="myController">
Please enter your name <apex:inputText value="{!shopper_name}"/>
<br/>
<apex:commandButton action="{!pageTwo}" value="Click for page two"/>
</apex:page>
Page two:
<apex:page controller="myController">
You entered: <apex:outputText value="{!shopper_name}" />.
</apex:page>
Controller:
public class myController {
public string shopper_name { get; set; }
public myController() {
shopper_name = null;
}
}
Custom settings are cached at the application level, maybe that's why it was suggested in the link above. I'm not sure if I'd recommend that approach, but you might be able to get it to work.
If you create a Custom Setting named "SessionData", and add your custom fields (that represent the data you want to store in session), you could save data to it like this:
Database.SaveResult result = Database.insert(new SessionData__c(YourFieldHere='Your value here etc'));
System.debug(result.getID());
Then use the resulting custom setting ID to store in a cookie. While custom settings can be accessed using normal SOQL, the advantage is that the data is cached and can be accessed like this:
if (SessionData__c.getAll().containsKey('unique ID from cookie here'))
{
System.debug(SessionData__c.getInstance('unique ID from cookie here').YourFieldHere);
}
Keep in mind that custom settings weren't really designed for this, so you'll need to periodically purge old custom settings data, as normal session management systems do.
See the Apex Custom Settings documentation for more details.
I think Visualforce View State might be useful to you:
Visualforce pages that contain a form component also contain an encrypted, hidden form field that encapsulates the view state of the page. This view state is automatically created, and as its name suggests, it holds the state of the page - state that includes the components, field values and controller state.
You should use Javascript cookies for this.
You could also use Apex cookies, but then you'd need to make sure that each request hits the server (and not the caching layer).
for Apex Cookie you can use following code:
//Setting Cookie
public void setCookie() {
Cookie userCookie = new Cookie('CookieName', fieldValueToBeStoredAsCookie, null, 315569260, false); //Here 315569260 represents cookie expiry date = 10 years. You can set this to what ever expiry date you want. Read apex docs for more details.
ApexPages.currentPage().setCookies(new Cookie[] {
userCookie
});
}
//Reading Cookie
Cookie cookie = ApexPages.currentPage().getCookies().get('CookieName');
if (cookie != null) {
String fieldValueToBeStoredAsCookie = cookie.getValue();
}