I am new to spring MVC and I am trying to get the session information in my controller class
Right now I am using
HttpSession objHttpSession = request.getSession(true);
if I want to get session creation time and session Id I am using
objHttpSession.getCreationTime();
objHttpSession.getId();
I want to know is there any spring MVC specific way to get the session details?
Thanks in advance
I usually declare a parameter of type HttpSession in my Spring MVC controller method when I need to access session details.
For example:
#RequestMapping("/myrequest")
public void handleMyRequest(HttpSession session, ...) {
...
}
I think it's the simplest way, but don't know if it fits your needs.
You can get the session in Spring MVC like this:
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
HttpSession session = attr.getRequest().getSession();
The currentRequestAttributes method return the RequestAttributes currently bound to the thread in which there is a current request and from that request you can get the session. This is useful when you need to get hold of the session in non-spring class. Otherwise you can just use:
#RequestMapping(...)
public void myMethod(HttpSession session) {
}
Spring will inject HttpSession instance into your controller's method.
Related
I have tow method and using Spring MVC, first is a method=RequestMethod.GET and there I set session.setAttribute("clientId", "abc").
Second method is a method=RequestMethod.POST where I do this:
HttpSession session = request.getSession();
System.out.println("-----" + (String)session.getAttribute("clientId"));
But always get null.
[Edit]
The thing here is the post method is not called by ModalandView("postpage"), its called by Http callout by Apache oltu internally
In Get method do
Session session = request.getSession(true);
session.setAttribute("clientId", "abc");
In Post do
String s = request.getSession().getAttribute("clientId");
I am trying to understand how to sending HttpSession as a parameter in the spring controller works.
I have a jsp which does a post request on clicking the submit button. In the controller, reading the sessions as follows
In the controller:
public ModelAndView viewEditFundClass(HttpServletRequest request,HttpServletResponse response,Model model){
HttpSession session = (HttpSession)request.getSession();
java.util.Date startDate = sesseion.getAttribute("startDate");
However, when I just change the controller to the following, I am still able to access the session
public ModelAndView viewEditFundClass(HttpServletRequest request,HttpServletResponse response, HttpSession session,Model model)
I would like to know how this is done in Spring, ie how did the post request pass the HttpSession as a parameter? will this session be valid?
Assuming you're using Spring 3+ #Controller and #RequestMapping handler methods, Spring defines a default set of supported argument types for your handlers
Session object (Servlet API): of type HttpSession. An argument of
this type enforces the presence of a corresponding session. As a
consequence, such an argument is never null.
Spring uses the strategy pattern to accomplish this, using the interface HandlerMethodArgumentResolver. It checks the parameter types of your handler methods and, for each type, tries to find a HandlerMethodArgumentResolver that will be able to resolve an argument for it.
For HttpSession, that implementation is ServletRequestMethodArgumentResolver.
I know how to get the caller Session, I inject the servlet request and get the Session object from it, but I don't know how to get the other callers sessions.
#Context
HttpServletRequest request;
...
Session session = request.getSession();
// Session[] a = request.getAllSessions(); // this would be great
I have Two different JSF page Let Us suppose A.jsf and B.jsf But Both calling same managed bean different methods ManagedBean.java
A.jsf is calling a SessionScoped Managed bean method where i set some attribute in Request class object
HttpServletRequest request = (HttpServletRequest) FacesContext
.getCurrentInstance().getExternalContext().getRequest();
request.setAttribute("token", requestToken.getToken());
request.setAttribute("tokenSecret", requestToken.getTokenSecret());
Then redirecting some other side like this
response.sendRedirect(requestToken.getAuthorizationURL());
Now after successful login i am opening another JSF page of my website suppose b.jsf and from this page i am calling method like this
<f:event listener="#{ManagedBean.redirectLogin2}" type="preRenderView" />
and calling same Managedbean but another method
public String redirectLogin2() throws TwitterException {
HttpServletRequest request = (HttpServletRequest) FacesContext
.getCurrentInstance().getExternalContext().getRequest();
}
But when i am doing in above method redirectLogin2()
request.getAttribute("token")
request.getAttribute("tokenSecret")
Both giving Null. What cab be the issue here?
Request scoped attribute life span will be lost on sendRedirect. You should set value on session scope.
HttpSession session=request.getSession();
session.setAttribute("token", requestToken.getToken());
session.setAttribute("tokenSecret", requestToken.getTokenSecret());
After setting value to session. You can access that from request like
HttpServletRequest request = (HttpServletRequest) FacesContext
.getCurrentInstance().getExternalContext().getRequest();
request.getSession().getAttribute("token");
request.getSession().getAttribute("tokenSecret");
Although, above code will work but that is not good practice. JSF has #SessionScoped annotation which will make available of your variable access with login session.
Using spring MVC, I need to store my object into session and I should use the same object in several jsp pages using jstl. I have tried like this:
ModelAndView modelAndView = new ModelAndView("admin/addproduct", "category", categorynameList);
But I can't access the category to other jsp pages except addproduct page.
How can I do that?
Spring MVC provides more than one mechanisms that hide the plain use of HttpSession from you.
Have a look at the #SessionAttributes annotation, which allows you to define the attributes that will be stored in the session by your controller; this mechanism is mainly intended to maintain the conversational state for your handler and that state is usually cleared once the conversation is complete.
Also, you can define your bean as session scoped in the application context and then make use of a ScopedProxyFactoryBean (by simply adding an <aop:scoped-proxy/> element in your bean definition), thus being able to inject that bean in your singleton controllers.
You can pass the session directly to any annotated controller method:
#RequestMapping("somePathName")
public String someHandler(HttpSession session) {
session.setAttribute(...
The annotation #SessionAttributes is used on class level. Typically it's used on the #Controller class. It's 'value' element is of type String[] whose values are the matching names used in #ModelAttribute either on method level or on handler's method parameter level.
Let's consider following arrangement:
#Controller
#SessionAttributes("visitor")
#RequestMapping("/trades")
public class TradeController {
#ModelAttribute("visitor")
public Visitor getVisitor (....) {
return new Visitor(....);
}
....
}
In above code, when a request comes in, the first thing Spring will do is to notice #SessionAttributes('visitor') and then attempt to find the value of 'visitor' in javax.servlet.http.HttpSession. If it doesn't find the value, then the method with #ModelAttribute having the same name 'visitor' (method getVisitor()) will be invoked. The returned value from such method will be used to populate the session with name 'visitor'.
Now that 'visitor' with it's value is already in HttpSession, let's consider following arrangement:
#Controller
#SessionAttributes("visitor")
#RequestMapping("/trades")
public class TradeController {
#RequestMapping("/**")
public String handleRequestById (#ModelAttribute("visitor") Visitor visitor,
Model model,
HttpServletRequest request) {
model.addAttribute("msg", "trades request, serving page " +
request.getRequestURI());
visitor.addPageVisited(request.getRequestURI());
return "traders-page";
}
.......
}
On finding #ModelAttribute("visitor") in the target handler method, Spring will retrieve the value of 'visitor' from the session and will assign the value to the Visitor parameter and will invoke the method. At this step, Spring doesn't care how the session was populated with 'visitor', Whether it was populated using the last arrangement or some other way, it doesn't matter, Spring only requires the annotation #SessionAttributes('visitor'), the handler method parameter with #ModelAttribute("visitor") and the value of 'visitor' in HttpSession. If spring can't find it in the session and last arrangement is not available then following exception will be thrown:
org.springframework.web.HttpSessionRequiredException: Expected session attribute 'visitor'
In other words: when the target handler method is invoked first time in a given session, then method with #ModelAttribute('visitor) is invoked, the returned value is populated in HttpSession and the handler method with the same value is invoked. For the subsequent requests within the same HTTPSession, Spring retrieves the same object from the session and doesn't call the method with #ModelAttribute('visitor') again till the end of the session
Following is the complete controller class:
#Controller
#SessionAttributes("visitor")
#RequestMapping("/trades")
public class TradeController {
#RequestMapping("/**")
public String handleRequestById (#ModelAttribute("visitor") Visitor visitor,
Model model,
HttpServletRequest request) {
model.addAttribute("msg", "trades request, serving page " +
request.getRequestURI());
visitor.addPageVisited(request.getRequestURI());
return "traders-page";
}
#ModelAttribute("visitor")
public Visitor getVisitor (HttpServletRequest request) {
return new Visitor(request.getRemoteAddr());
}
}
In above example we are tracking the user visited pages within the same HTTP session. We are using the wildcard '/**' so that all request starting with 'trades' will map to this controller.
Inject session to your controller classes, store your object there and use it when you need it, e.g.:
#Controller
public class SomeController {
//#Autowired
//private HttpSession session; This is not desired. See the discussion in the
//comments.
#RequestMapping("somePathName")
public String someHandler(HttpSession session) { //Session will be injected by
//Spring without any additional annotations.
//...
session.setAttribute("category", yourObject);
}
}
If you need to access category on other pages than admin/addproduct you will need to add it to respective models as follows:
#RequestMapping("somePathName")
public String someHandler(Model model) {
//...
model.addAttribute("category", yourObject);
//...
return "yourPageName";
}
Update: according to ALex's comment that injecting HttpSession instance into field is strongly not desired due to thread safety concerns I've changed the source respectively.