user979899
user979899

Reputation: 153

Spring controller to reload same page when form is submitted

I'm having a problem with creating a Spring controller that would reload the same page when a form is filled in. What I want to achieve is a page for changing passwords. It should ask for old password, a new password and the new password re-typed. When the user fills in everything and submits the form, the action should be the same page and the controller should be able to either show something like "passwords do not match" or "password successfully changed". I know how to achieve this by using several controllers but I think it would be better to use one controller.

Below is my controller:

package controllers;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import models.Password;



@Controller
public class ChangePassword {
    @RequestMapping(value = "/changepassword", method = RequestMethod.GET)
    public ModelAndView changePassword(@ModelAttribute("changepassword")Password password, BindingResult result) {
        if(password.isEmpty())
        {
            return new ModelAndView("changepassword", "command", new Password());
        }
        else if(password.isValid())
        {
            return new ModelAndView("changepassword", "message", "The password was successfully changed!");
        }
        else{
            return new ModelAndView("changepassword", "message", "The passwords did not match and/or the password was not 8 at least 8 characters long.");
        }       
    }

The first time the page loads it shows the form correctly, but if one leave the password empty and submit then glassfish shows:

"org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute"

I don't understand why this happens, I thought it should show the form like the first time accessed.

In fact what I need is to get the Password model to the viewer and also some text (error message or successfull message). I have seen people returning maps to the viewer but I haven't succeeded doing that.

Upvotes: 5

Views: 43644

Answers (1)

danny.lesnik
danny.lesnik

Reputation: 18639

You should map request as GET and POST. GET for rendering page and its messages and POST for the submit itself.

You should redirect to avoid Duplicate submit problem.

and in order to show message in model and view you should use FlashScope implementation.

See this post for details: Spring MVC custom scope bean

You can do it this way:

@Controller
public class ChangePassword {
    @RequestMapping(value = "/changepassword", method = RequestMethod.GET)
 public ModelAndView renderCPassPage(@ModelAttribute("changepassword")Password password, BindingResult result) {
       ModelAndView mv = new ModelAndView("changePassword");
       mv.addObject("password" password);
       return mv;
    }

   @RequestMapping(value = "/changepassword", method = RequestMethod.POST)
 public ModelAndView renderCPassPage(@ModelAttribute("changepassword")Password password, BindingResult result) {
       ModelAndView mv = new ModelAndView("redirect:changepassword");
          if(password.isEmpty())
        {
            return new ModelAndView("message", "password Empty");
        }
        else if(password.isValid())
        {
            return new ModelAndView("message", "The password was successfully changed!");
        }
        else{
            return new ModelAndView("message", "The passwords did not match and/or the password was not 8 at least 8 characters long.");
        }       
    }

Upvotes: 3

Related Questions