Spring : How to use session in Spring MVC - spring

I have a login form and I want to display Name of user who logined .I want to use session in Spring MVC, but it's not work
This is UsersController
#PostMapping("/room/saveRegister")
public String saveRegister(#Valid Users users, BindingResult result, RedirectAttributes redirect) {
if (result.hasErrors()) {
return "register";
}
usersService.save(users);
redirect.addFlashAttribute("success", "Saved user successfully!");
return "redirect:/room";
}
#GetMapping("/room/login")
public String login(Model model) {
model.addAttribute("users", new Users());
return "login";
}
#PostMapping("/room/loginRoom")
public String login(#ModelAttribute("users") Users user, ModelMap modelMap, RedirectAttributes redirect,HttpSession session) {
if(usersService.findByEmailAndPass(user.getEmail(),user.getPass()) != null) {
session.setAttribute("name",user.getName());
return "redirect:/room";
}else {
modelMap.put("error", "Email or Password is not correct. Pleased Try Again");
return "login" ;
}
}
And in file .html,I add
<li ><span th:text ="${session.name}"></span></li>
But when I login successful . Name of User is not display . Session is not work. I don't know why

You need to use ${sessionScope.name} instead of ${session.name}
More details can be found at Examples of EL Expressions

Refer this
Using Http Session With Spring Based Web Applications

Related

SPRING MVC: Defined HttpSession in One Method is Not Available to Another Method

I am facing a problem regarding to the Httpsession that I implementing in the Spring MVC project.
First of all, after the user successfully login, I will take the Httpsession object in loginAuthentication controller and set attribute with the name and value I want. (Shown in following figure).
A.java controller file,
#RequestMapping(value="login-authentication", method = RequestMethod.POST)
public String authentication(#Valid #ModelAttribute("systemAccount") SystemAccount systemAccount,
BindingResult bindingResult, Model model, HttpServletRequest request){
if (bindingResult.hasErrors()) {
model.addAttribute(GenericConstant.MessageAttributeName.ERROR_MSG_NAME.toValue(), SystemMessage.SystemException.LOGIN_INCORRECT_USERNAME_PASSWORD.toValue());
model.addAttribute("systemAccount", new SystemAccount());
return "index";
}else {
if (systemAccountService.authenticate(systemAccount.getUsername(), systemAccount.getPassword()) != null &&
!"".equals(systemAccountService.authenticate(systemAccount.getUsername(), systemAccount.getPassword()))) {
SystemAccount dbSystemAccount = systemAccountService.authenticate(systemAccount.getUsername(), systemAccount.getPassword());
request.setAttribute(SessionAttribute.AttributeName.LOGIN_ACC_ID.toValue(),dbSystemAccount.getAccountID());
//check account role
if(dbSystemAccount.getCounterStaff()!= null && !"".equals(dbSystemAccount.getCounterStaff())){
CounterStaff counterStaff = dbSystemAccount.getCounterStaff();
request.setAttribute(SessionAttribute.AttributeName.LOGIN_ACC_NAME.toValue(), counterStaff.getStaffName());
request.setAttribute(SessionAttribute.AttributeName.LOGIN_ACC_ROLE.toValue(), GenericConstant.SystemRole.COUNTER_STAFF.toValue());
}else if(dbSystemAccount.getCustomer()!= null && !"".equals(dbSystemAccount.getCustomer())){
Customer customer = dbSystemAccount.getCustomer();
request.setAttribute(SessionAttribute.AttributeName.LOGIN_ACC_NAME.toValue(), customer.getCustomerName());
request.setAttribute(SessionAttribute.AttributeName.LOGIN_ACC_ROLE.toValue(), GenericConstant.SystemRole.CUSTOMER.toValue());
}else if(dbSystemAccount.getManager()!= null && !"".equals(dbSystemAccount.getManager())){
Manager manager = dbSystemAccount.getManager();
request.setAttribute(SessionAttribute.AttributeName.LOGIN_ACC_NAME.toValue(), manager.getManagerName());
request.setAttribute(SessionAttribute.AttributeName.LOGIN_ACC_ROLE.toValue(), GenericConstant.SystemRole.MANAGER.toValue());
}else if(dbSystemAccount.getDoctor()!= null && !"".equals(dbSystemAccount.getCounterStaff())){
Doctor doctor = dbSystemAccount.getDoctor();
request.setAttribute(SessionAttribute.AttributeName.LOGIN_ACC_NAME.toValue(), doctor.getDoctorName());
request.setAttribute(SessionAttribute.AttributeName.LOGIN_ACC_ROLE.toValue(), GenericConstant.SystemRole.DOCTOR.toValue());
}
request.setAttribute(SessionAttribute.AttributeName.LOGIN_DATE.toValue(), DateTimeUtil.getCurrentDate());
return "mainPage";
}else {
model.addAttribute(GenericConstant.MessageAttributeName.ERROR_MSG_NAME.toValue(), SystemMessage.SystemException.LOGIN_INCORRECT_USERNAME_PASSWORD);
model.addAttribute("systemAccount", new SystemAccount());
return "index";
}
}
}
After everything is ready, the controller will navigate user to the main page and the main page able to access all the defined variable without issue. (The following figure shown the controller that mapped with mainPage).
A.java controller file,
#RequestMapping(value = "/mainPage", method = RequestMethod.GET)
public String renderMainPageView(Model model, HttpServletRequest request) {
if(request.getAttribute(SessionAttribute.AttributeName.LOGIN_CHECK.toValue()) != null) {
model.addAttribute(SessionAttribute.AttributeName.LOGIN_ACC_ID.toValue(),
request.getAttribute(SessionAttribute.AttributeName.LOGIN_ACC_ID.toValue()));
model.addAttribute(SessionAttribute.AttributeName.LOGIN_ACC_NAME.toValue(),
request.getAttribute(SessionAttribute.AttributeName.LOGIN_ACC_NAME.toValue()));
model.addAttribute(SessionAttribute.AttributeName.LOGIN_ACC_ROLE.toValue(),
request.getAttribute(SessionAttribute.AttributeName.LOGIN_ACC_ROLE.toValue()));
model.addAttribute(SessionAttribute.AttributeName.LOGIN_DATE.toValue(),
request.getAttribute(SessionAttribute.AttributeName.LOGIN_DATE.toValue()));
return "mainPage";
}else {
model.addAttribute("systemAccount", new SystemAccount());
return "index";
}
}
In the navigation menu of main page, I click on the selection to direct me to add manager web page. (The following shown the link).
<a href="addManager" target="ifrm" >Add New Account</a>
The controller that mapped with the link (GET) able to detect. However, this controller (renderAddManagerView) does not recognised the HTTP session that I defined earlier when I try to access using the getAttribute method in the if condition. It keep showing null value (Shown in the following figure.
B.java controller file,
#RequestMapping(value = "/addManager", method = RequestMethod.GET)
public String renderAddManagerView(Model model, HttpSession httpSession) {
if(httpSession.getAttribute(SessionAttribute.AttributeName.LOGIN_CHECK.toValue()) != null) {
model.addAttribute("manager", new Manager());
model.addAttribute(FormSelectionValue.FormSelectionAttributeName.COUNTRY_SELECTION.toValue(), FormSelectionValue.COUNTRY_SELECTION_LIST);
model.addAttribute(FormSelectionValue.FormSelectionAttributeName.GENDER_SELECTION.toValue(), FormSelectionValue.GENDER_SELECTION_LIST);
return "addManager";
}else {
model.addAttribute("systemAccount", new SystemAccount());
return "index";
}
}
So I am not sure what is the issue for my code and there is no error message is displayed.
I have solved the issue by using the HttpServletRequest instead of HttpSession.
Now my session will not be loss even redirect or navigate to any pages in JSP.
Something like this:
#RequestMapping("/renderview", method = RequestMethod.GET)
#Controller
public class TestController {
#RequestMapping(method = RequestMethod.GET)
public String myMethod(HttpServletRequest request)
{
request.getSession().setAttribute("mySession", "XXX");
return "jspview";
}
}
Reference: Set session variable spring mvc 3

How to pass object or data from one to another controller in spring-boot web application?

I want to take a some of data from users' input and then I want to transfer these between controllers.But this transfer must be done in the background for security. I don't want to send parameters on the URL.
I want to send the user object created in page1 controller to page2.
I used the model method for this, but I was not successful.
#Controller
public class DemoController {
...
..
.
#GetMapping("/page1")
public String page1(Model model) {
User user = new User();
user.setName("TestName");
user.setSurname("TestSurname");
user.setMail("xyzabc#gmail.com");
model.addAttribute("user", user);
return "redirect:/page2";
}
#GetMapping("/page2")
public String page2(#ModelAttribute("user") User user, Model model) {
System.out.println(user.toString());
return "page2";
}
.
..
...
}
How do I transfer objects?
There are 2 solutions for this question:
Solution 1: Store object in session
Code example:
#GetMapping("/page1")
public String page1(Model model, HttpSession session) {
...
session.setAttribute("user", user);
return "redirect:/page2";
}
#GetMapping("/page2")
public String page2(Model model, HttpSession session) {
User user = null;
if (session.getAttribute("user") != null) {
user = (User) session.getAttribute("user");
System.out.println(user.toString());
}
return "page2";
}
Solution 2: use forward instead of redirect
Code example:
#GetMapping("/page1")
public String page1(Model model) {
...
model.addAttribute("user", user);
return "forward:/page2";
}
you can use either :
session
or
2)forward:/page2 instead of redirect

Spring Security - logout with my own message

I'm developing Spring boot application. Thymeleaf on front is also used. Now I'm working on changing username(email). After confirmation from email I'm returning "redirect:/logout" in controller. I want to add a message that email is changed and user have to login again with new username(mail).
This is my configuration of Spring Security:
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
And controller fragment:
#RequestMapping(value = "/confirmmail/{hash}", method = RequestMethod.GET)
public String confirmMail(#PathVariable String hash,
RedirectAttributes redirectAttributes,
Model model) {
Optional<User> userOptional = userService.getUserByConfirmChangeEmailHash(hash);
if(userOptional.isPresent()){
User user = userOptional.get();
user.setEmail(user.getTemporaryEmail());
user.setTemporaryEmail(null);
userService.save(user);
redirectAttributes.addFlashAttribute("logoutMessage",messageService.getMessage("user.profile.email.changed.success"));
// redirectAttributes.addAttribute("message",messageService.getMessage("user.profile.email.changed.success"));
// model.addAttribute("logoutMessage",messageService.getMessage("user.profile.email.changed.success"));
return "redirect:/logout";
}else{
model.addAttribute("message",messageService.getMessage("user.profile.email.changed.failed"));
}
return "/user/index";
}
As you can see, I've tried to use RedirectAttributes, flash atributes, and simply to model.
Unfortunately, after redirecting to login page my data from model are not present.
How can I solve this problem?

Spring Boot application form validation is intercepted by /error page

Currently I am working on a project which used Spring Boot 1.2.7, and freemarker as page template engine.
I am trying to use Bean Validation as before, but it does not work as expected.
#RequestMapping(value = "/signup", method = RequestMethod.POST)
public String signup(#Valid #ModelAttribute("signup") SignupForm signup, BindingResult result) {
log.debug("signup form #" + signup);
if (result.hasErrors()) {
return "/signup";
}
//AccountDetails details = accountService.register(form);
return "redirect:/login";
}
When the bean validation is failed, it redirected to Spring Boot built-in /error page instead of displaying error messages in the signup page.
Your issue in SignupForm object and signup model attribute. Spring can not map both.
You need to redirect to signup page like :
#RequestMapping(value = "/signup", method = RequestMethod.POST)
public String signup(#Valid #ModelAttribute("signup") SignupForm signup, BindingResult result) {
log.debug("signup form #" + signup);
if (result.hasErrors()) {
return "signup";
}
//AccountDetails details = accountService.register(form);
return "redirect:/login";
}

Spring MVC handle Exceptions and how to show in same view

If I handle exceptions with #ControllerAdvice and #ExceptionHandler How can I show error message to user in the same View. For ex. suppose user in "customer/new" view. and invoke "save" action, then it will go to controller and I call methods service layer. but if internal exception occurred in service layer, I want to show error message on same "customer/new" View.
I have written a separate class to handle exceptions as follow.
#ControllerAdvice
public class DefaultControllerHandler {
#ExceptionHandler({MyProjectException.class, DataAccessException.class})
public ResponseEntity<String> handleInternalErrorException(Exception e) {
logger.error(e.getMessage(), e);
return new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Appreciate your ideas.
Thanks!
You can use flash redirect attributes.
#RequestMapping(value = "/administrator/users", method = RequestMethod.POST)
public String adminAddUser(#ModelAttribute("user") #Valid User user, BindingResult bindingResult, Model model, RedirectAttributes redirectAttrs) {
String redirectUrl = "/administrator/users";
try {
userService.save(user);
} catch (YourServiceException e) {
redirectAttrs.addFlashAttribute("errorMessage", "error occured: " + e.getMessage());
redirectAttrs.addFlashAttribute("userObject", user);
redirectUrl = "/administrator/users?form"; // If error - return to same view
}
return "redirect:" + redirectUrl;
}
#RequestMapping(value = "/administrator/users", params = "form", method = RequestMethod.GET, produces = "text/html")
public String adminUsersList(#ModelAttribute("errorMessage") final String errorMessage, #ModelAttribute("userObject") final User user Model model) {
if(user == null) {
user = new User();
}
model.addAttribute("user", user);
if(errorMessage != null) {
model.addAttribure("errorMessage", errorMessage);
}
return "administrator/users/create";
}
In that case you must have section on your users.jsp page to show errorMessaage. Something like this:
<c:if test="${not empty errorMessage}">${errorMessage}</c:if>
If you can fetch url path and redirectAttributes from controller method - you can do this through #ControllerAdvice
The only solution I can think about is make your call to the service layer AJAX and then redirect only if there are no errors, if not display the error message.
It might look something like this in your Javascript file
$("#someButton").click(function(){
//make your ajax call
if (noError){
window.location.href = contextPath+"/somePath";
}
else{
//display your error message
}
});

Resources