Accessing Session Object in JSP - spring

I am setting a Session using Spring HttpSession.
Here session is set as a object containing four/five fields.
I can access this session at my jsp but when i want to access the individual records within the Sessionobject. it gives null.
Help please
// This is session data model
public class UserServiceModel implements Serializable
{
public String MobileNo;
public String CityName;
public String UserName;
public String UserPwd;
public String UserRole;
public String Device;
public UUID SessionID;
// getters,setters
}
// code for setting session
StaffModel record1 = (StaffModel) data.get("records");
UserServiceModel sessionData = new UserServiceModel();
sessionData.setMobileNo(record1.getMobileNo());
sessionData.setCityName(record1.getCity());
sessionData.setUserName(record1.getFirstName());
sessionData.setUserRole(record1.getRole());
sessionData.SessionID = UUID.randomUUID();
System.out.println("SessionID=" + sessionData.MobileNo);
sessionObj.setAttribute("SessionData" , sessionData); // setting session Data
// this is jsp code
<% String ses = (String)session.getAttribute("SessionData.MobileNo");
out.print("Hello User:"+ses);
%>
Output gives: null

You have update the JSP code like below. As session.getAttribute() method return object as value.
<%
UserServiceModel obj= (UserServiceModel)session.getAttribute("SessionData");
String ses = obj.getMobileNo();
out.print("Hello User:"+ses);
%>

I have solved this
Here is the code:
sUserName = <% UserServiceModel obj = (UserServiceModel)session.getAttribute("SessionData");
out.print(obj.getUserName());
// at top of the jsp page i have to import the model UserServiceModel
<%# page import="org.kmsg.listobject.UserServiceModel"%>
and now userName which exist within the object SessionData is accessible in variable "sUserName"
Thanks...

Related

Strange behavior : Spring Session Attributes vs ModelAttribute

I got a very strange issue with Spring MVC 4.0.6, hosted on JBoss 7.2. When updating an existing user, the submitted information sometimes get transferred to the POST RequestMapping controller method (validateUpdate method below).
UserController.java
#Controller
#RequestMapping(value = "/security/user")
#SessionAttributes(value = {"userForm", "user"})
public class UserController {
private final String CREATE_VIEW = "user/createOrUpdate";
private final String READ_VIEW = "user/readOrDelete";
private final String UPDATE_VIEW = CREATE_VIEW;
private final String DELETE_VIEW = READ_VIEW;
#Autowired
private LocationService locationService;
#Autowired
private SecurityService securityService;
#Autowired
private UserValidator userValidator;
#InitBinder("userForm")
protected void initBinder(WebDataBinder binder) {
binder.setValidator(userValidator);
binder.setDisallowedFields("strId");
}
#ModelAttribute("regions")
public List<Region> populateRegions() {
Locale locale = LocaleContextHolder.getLocale();
List<Region> regions = this.locationService.lstRegions(locale.getLanguage());
return regions;
}
#RequestMapping(value = "/update/{intUserId}", method = RequestMethod.GET)
public String updateUser(#PathVariable Integer intUserId, Model model) {
User user = this.securityService.findUserByPk(intUserId);
if (user != null) {
UserForm userForm = new UserForm();
userForm.setUser(user);
model.addAttribute(userForm);
}
return UPDATE_VIEW;
}
#RequestMapping(value = "/update/validate", method = RequestMethod.POST)
public String validateUpdate(#Valid #ModelAttribute("userForm") UserForm userForm,
BindingResult result,
Model model,
RedirectAttributes redirectAttributes,
SessionStatus status) {
return this.performCreateOrUpdateOperation(userForm, result, model, redirectAttributes, status);
}
private String performCreateOrUpdateOperation(
UserForm userForm,
BindingResult result,
Model model,
SessionStatus status) {
if(result.hasErrors()) {
return UPDATE_VIEW;
} else {
User user = userForm.getUser();
this.securityService.validateCreateOrUpdateUser(result, user);
if (result.hasErrors() == false) {
if (userForm.isNew()) {
this.securityService.addUser(user);
} else {
this.securityService.updateUser(user);
}
model.addAttribute(user);
status.setComplete();
return "user/success";
} else {
return UPDATE_VIEW;
}
}
}
}
Form Bean
public class UserForm {
private String strUserIdToSearch = "";
private String strId = "0";
private String strUserId = "";
private String strFirstName = "";
private String strLastName = "";
private String strEmail = "";
private String strRegionId = "0";
private boolean booArchived = false;
public User getUser() {
User user = new User();
user.setIntId(Integer.valueOf(this.strId));
user.setStrUserId(this.strUserId);
user.setStrFirstName(this.strFirstName);
user.setStrLastName(this.strLastName);
user.setStrEmail(this.strEmail);
Region region = new Region(Integer.valueOf(this.strRegionId));
user.setRegion(region);
user.setBooArchived(this.booArchived);
return user;
}
public void setUser(User user) {
this.strUserIdToSearch = user.getStrUserId();
this.strId = String.valueOf(user.getIntId());
this.strUserId = user.getStrUserId();
this.strFirstName = user.getStrFirstName();
this.strLastName = user.getStrLastName();
this.strEmail = user.getStrEmail();
this.strRegionId = String.valueOf(user.getRegion().getIntId());
this.booArchived = user.getBooArchived();
}
...getters and setters...
}
JSP (removed styling for clarity)
crudMethod is a JSP tag returning "create", "read", "update" or "delete" depending on ${requestScope['javax.servlet.forward.request_uri']}
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<spring:url var="userFormAction" value="/rest/security/user/${crudMethod}/validate" />
<form:form id="userForm" modelAttribute="userForm" action="${userFormAction}" method="POST">
<form:hidden path="strId" />
<form:hidden path="strUserId" id="strUserId" />
<form:hidden path="strLastName" id="strLastName" />
<form:hidden path="strFirstName" id="strFirstName" />
<form:hidden path="strEmail" id="strEmail" />
<form:select id="strRegionId" path="strRegionId">
<form:option value="0" label="${strSelectRegionLabel}" />
<form:options items="${regions}" itemValue="intId" itemLabel="${strRegionLabel}" />
</form:select>
</form:form>
So, when I submit the form, and for instance, change the region to another ID in the list (let's say from 1 to 6). Sometimes it works, sometimes not. By "works", I mean I hit the success page, then I go back to see the user again. Sometimes it stays at 1, sometimes it's changed to 6.
I have found a pattern/workaround that works all the time to reproduce the issue:
Load the update form (UserController > updateUser)
Change the region from 1 to 6
Click Save. Form submits so the UserController.validateUser method is being invoked.
Got the success page. On that success page I got a link to the read operation for the user. Clicking that link, I realize that the region did not change (the main problem). There is a link to update a user on the read page.
Re-do the exact same change that I did at step #2.
Click Save. Form submits and I got the success page view.
Click the read hyperlink again, and now I see that the change worked.
Question is: WHY? Am I missing something??
Note: It's not related to the business layer. I have tested it and it's stable. That is certainly related to my use of the Spring MVC Framework.
Browser is IE11.
Thank you for help.
* UPDATE 2015-06-29 *
After a few more searches, I found that:
when it does NOT work, the request Content-Length header value is 0.
when it works, there is a value (eg: 146).
the request message body is always correct, like so:
strId=THE_ID&strUserId=THE_USERID&strLastName=THE_LASTNAME&strFirstName=THE_FIRSTNAME&strEmail=THE_EMAILADDRESS&strRegionId=THE_REGIONID&booArchived=false
Please note that "THE_REGIONID" is good every single time.
Related resources
Challenge-Response Authentication and Zero-Length Posts
Form Submit Not working on IE intermittently with Spring MVC in backend
<form:select id="intRegionId" path="strRegionId">
I think the id in the form:select is the culprit . It doesn't match the attribute name in UserForm, which is "strRegionId". And therefore it doesn't bind. Change the id value to strRegionId

AJAX jQuery CRUD with spring mvc without repeating RequestMethods

i have a page with a form and i have a AJAX function that returns a json with user details to fill some fields of that form and also in the same page i have a button to create a user from the information of that form
my problem is that to do this i have 3 controllers of the same page like this
this controllers returns the form with a GET method
#Controller
#RequestMapping("forms")
public class myController {
#RequestMapping(value = "myForm", method = RequestMethod.GET)
public String getPage (Model model) {
return "forms/myForm";
}
this controller is the one that gets me the some of the data in the form
RequestMapping(value = "myForm", method = RequestMethod.POST)
public #ResponseBody String searchSomeFields(#RequestBody final String json, Model model)
throws IOException
{
ObjectMapper mapper = new ObjectMapper();
User objectMap = mapper.readValue(json, User.class);
//get some data a fill some fields in the form
return toJsonInsertar(objectMap);
}
and in this controller i do the insert
RequestMapping(value = "myForm", method = RequestMethod.POST)
public #ResponseBody boolean insertUser(#RequestBody final String json, Model model)
throws IOException
{
ObjectMapper mapper = new ObjectMapper();
User objectMap = mapper.readValue(json, User.class);
//insert the user with all the data in the form
return toJsonInsertar(objectMap);
}
i try using two GET in the firts two controllers but i get a error saying that i already have a controller with the same requestMethod and value, i try puting PUT in the third controller that does the insert and it worked, but i read that PUT is used to do EDITS.
how can i do this insert with what i have ?

how to to call db access method from controller to DAO class in struts

i want to call a method from controller i.e servlet. The method is located in seperate java(DAO) class. The issue is how to pass form variables from controller to java(DAO) class.
You can do this by using a bean (POJO) class. I will explain it by using a simple example.
If your form has a field "UserName" , In your bean (POJO) class create a variable called UserName create getter/setter mathods
Ex: **JSP**
( User Name: <input type="text" name="UserName" value="UserName"/> )
**Bean (POJO) class :**
public class InputBean {
private String UserName;
public void setUserName(String UserName) {
this.UserName = UserName;
}
public String getUserName() {
return UserName;
}
}
Then you can pass the form varibles from controller to DAO **by using InputBean** class (By creating InputBean Objects in both DAO and Controller) **as the intermediate class**
assume that you have a method called "add" in DAO
public String add(inputBean inputBean) {
// your code here
try {
// your code here
//assume that database mapping class to relavent database table is User
User task = new User();
task.setUserName(inputBean.getUserName); //here the form data is passed
}
//your code here
}
Then in action class you can call that method
----Action Class----
InputBean inputBean = new TaskInputBean();
public String insert() {
//your code here
try {
dao.add(inputBean);
//your code here
}
return result;
}

How to view data in Jsp when added in a model using spring mvc

I have the following flows for an application when a submit button is clicked:
1)The viewActivity method is called from ActivityController.java
ActivityController.java
#ActionMapping(params = "ActivityController=showActivity")
public void viewActivity(#RequestParam Integer index, ActionResponse response, Model model, #ModelAttribute Header header,
....
model.addAttribute("recoveryForm", new RecoveryForm(detailsResult.getDetails()));
response.setRenderParameter("ServiceController", "showService");
}
2) Then showRecovery method is called from serviceConroller as show below:
ServiceController.JAVA
#RenderMapping(params = "ServiceController=showService")
public String showRecovery(#ModelAttribute recoveryForm form, #ModelAttribute header header) {
.....
return service;
}
Then my service.jsp is displayed
Basically i have to display the value of a variable which is detailName found in DetailsResult.getDetails() object which i have added to my model as
it can be seen in viewActivity method found in ActivityController.java showed ealier.
I know when we add model.addAttribute it should be able to be displayed on this jsp using the following tag :
<form:input path="..." />
But in this case it is added to as a constructor argument as shown below:
model.addAttribute("recoveryForm", new RecoveryForm(detailsResult.getDetails()));
I have the following variable on my RecoveryForm:
public class RecoveryForm implements Serializable {
private CDetails Cdlaim;
private Action addAction;
private String addRemark;
private String remarks;
public RecoveryForm(CDetails Cdlaim) {
...
}
...
}
However i don't have the detailsResult in my RecoveryForm.
Any idea how i can get a value which is in DetailsResult.getDetails() in my service.jsp?
I believe you are looking at this the wrong way. The value of DetailsResult.getDetails() is obviously stored in RecoveryForm as a property somehow. So, I'm going to assume your RecoveryForm looks something like:
public class RecoveryForm {
private String details;
public RecoveryForm(String details) {
this.details = details;
}
public String getDetails() {
return details;
}
}
When you bind to a form in your jsp, you need to nest your <form:input ...> tag in a <form:form ...> tag:
<form:form commandName="recoveryForm" ...>
<form:input path="details" ... />
</form:form>
The commandName is key to telling the form the model object from which you will be pulling form values. In this case you are getting the details property from the RecoveryForm instance named recoveryForm. Make sense?

Strange Spring #SessionAttributes Behavior

I'm using #SessionAttributes on 2 controllers and am experiencing some very strange behavior. My first controller (ViewController) is simply a view controller that displays JSP pages. The other is a controller that handles Ajax requests (AjaxController). I have a session attribute that is simply an object that has a HashMap as a member. The object is a wrapper around the map. The map is populated from the database and put in the session, which displays fine via the ViewController. However, when I do a delete from the map via an ajax request (AjaxController) and refresh the page, ViewController SOMETIMES shows that the element is removed, yet other times the element is still there. Here's code snippets:
ViewController (the homepage simply displays the contents of the map contained by userSettings
#Controller
#SessionAttributes({"userSettings"})
public class ViewController {
#RequestMapping(value="/", method=RequestMethod.GET)
public String home(ModelMap model) {
UserSettings userSettings = (UserSettings) model.get("userSettings");
String userListenersJson = userSettings.toJson(); // for bootsrtapping the js on the front end
return "views/home";
}
}
AjaxController:
#Controller
#SessionAttributes({"userSettings"})
public class AjaxController {
#RequestMapping(value="/users/listeners/{externalId}", method=RequestMethod.DELETE)
public #ResponseBody
AjaxResponse<?> deleteListener(ModelMap model,
#PathVariable long externalId) {
UserSettings userSettings = (UserSettings) model.get("userSettings");
userSettings.removeSetting(externalId);
return new AjaxResponse<String>(null, true);
}
}
Am I using #SessionAttributes wrong here? Why would this work sometimes and not others? I've also tried putting all of the view and ajax functionality in the same controller and experienced the same behavior.
Thanks for any help!
EDIT:
I've refactored my code a bit to use the UserPrincipal via springsecurity. My understanding is that this object is stored in the session. Regardless, I'm seeing exactly the same behavior.
Here's the UserPrincipal constructor that populates the user settings map. I've set breakpoints here to ensure that the correct listenerDBOs are set - they are, every time. This is the only time the listeners get set from the db into the UserSettings object in CustomUserPrincipal. All other adds/removes are done via the controllers (quick aside: adds never fail... only removes):
public CustomUserPrincipal(UserDBO userDBO) {
// set UserSettings obj
UserSettingsAdapter.addListeners(userDBO.getUserListenerDBOs(), userSettings);
}
The UserSettings object itself:
public class UserSettings implements Serializable {
private static final long serialVersionUID = -1882864351438544088L;
private static final Logger log = Logger.getLogger(UserSettings.class);
private Map<Long, Listener> userListeners = Collections.synchronizedMap(new HashMap<Long, Listener>(1));
// get the listeners as an arraylist
public List<Listener> userListeners() {
return new ArrayList<Listener>(userListeners.values());
}
public Map<Long, Listener> getUserListeners() {
return userListeners;
}
public Listener addListener(Listener listener) {
userListeners.put(listener.getId(), listener);
return listener;
}
// I'm logging here to try and debug the issue. I do see the success
// message each time this function is called
public Listener removeListener(Long id) {
Listener l = userListeners.remove(id);
if (l == null) {
log.info("failed to remove listener with id " + id);
} else {
log.info("successfully removed listener with id " + id);
}
log.info("Resulting map: " + userListeners.toString());
log.info("Map hashcode: " + userListeners.hashCode());
return l;
}
public Listener getListener(long id) {
return userListeners.get(id);
}
}
This is the helper function in the UserSettingsAdapter class that adds to the UserSettings object, called from CustomUserDetails constructor:
public static void addListeners(Set<UserListenerDBO> userListeners, UserSettings userSettings) {
for (UserListenerDBO userListenerDBO : userListeners) {
if (userListenerDBO.isActive()) {
addListener(userListenerDBO, userSettings);
}
}
}
I've also changed the controller code to user the CustomUserPrincipal object instead of #SessionAttributes:
In ViewController:
#RequestMapping(value="/", method=RequestMethod.GET)
public String home(ModelMap model) {
CustomUserPrincipal userPrincipal = authenticationHelpers.getUserPrincipal();
UserSettings userSettings = userPrincipal.getUserSettings();
String userListenersJson = userSettings.toJson();
return "views/home";
}
In AjaxController:
#RequestMapping(value="/users/listeners/{externalId}", method=RequestMethod.DELETE)
public #ResponseBody
AjaxResponse<?> deleteListener(ModelMap model,
#PathVariable long externalId) {
CustomUserPrincipal userPrincipal = authenticationHelpers.getUserPrincipal();
UserSettings userSettings = userPrincipal.getUserSettings();
userSettings.removeListener(externalId);
return new AjaxResponse<String>(null, true);
}
I hope this helps shed some light on the issue!
I ran into a similar problem with #SessionAttributes. A controller had a #SessionAttributes annotation at the class level, and one of the methods handled POST requests, and included an instance of the session-managed object as an argument. This instance was saved to the database, but was re-used by subsequent requests, causing some data corruption. We had to add another method argument of type SessionStatus, and call SessionStatus.setComplete(). This caused the instance to be removed from the session, and prevented reuse and corruption. So try adding a SessionStatus instance to your controllers' handler methods, and invoke setComplete() where appropriate.
EDIT: I accidentally referenced the getter isComplete() in my initial answer; I meant to reference the setter setComplete().
#SessionAttributes is specific to a Controller and is not shared among several Controllers.
Instead, consider using manually session.setAttribute (class HttpSession).
You should have a look here : http://beholdtheapocalypse.blogspot.fr/2013/01/spring-mvc-framework-sessionattributes.html

Resources