How pass POST parameters from controller to another Controller Spring MVC? - spring-mvc

I have startController and start view. In this view I input number and amount and validate it. If validation was successful, I want pass this parameters(number and amount) to another controller, and after that make some operations with it, in this controller. I see two way:
make this operations in first controller, in another methods and use second view for it. But my controller will very big and all logic will be this.
create second controller and second view and pass parameters to this controller.
I make this:
#Controller
#RequestMapping("/")
public class StartController {
#Autowired
private ValidateService validateService;
#RequestMapping(method = RequestMethod.GET)
public ModelAndView printWelcome() {
ModelAndView modelAndView = new ModelAndView("start");
return modelAndView;
}
#RequestMapping(value = "process", method = RequestMethod.POST)
public ModelAndView process(HttpServletRequest request) {
ModelAndView modelAndView;
String phoneNumber = request.getParameter("phone_number");
int amount = Integer.parseInt(request.getParameter("amount"));
String result = validateService.validate(phoneNumber, amount);
if (!result.equals("OK")) {
modelAndView = new ModelAndView("start");
modelAndView.addObject("result",result);
}else {
modelAndView = new ModelAndView("redirect:/check/process");
modelAndView.addObject("phone_number", phoneNumber);
modelAndView.addObject("amount",amount);
}
return modelAndView;
}
and if result != OK I redirect to new controller
#Controller
#RequestMapping("/check")
public class CheckController {
#RequestMapping(value = "process", method = RequestMethod.GET)
public ModelAndView process(HttpServletRequest request) {
ModelAndView modelAndView = new ModelAndView("check");
String phoneNumber = request.getParameter("phone_number");
int amount = Integer.parseInt(request.getParameter("amount"));
return modelAndView;
}
}
But I need pass parameters with RequestMethod.POST and it will not work. How do it?

You can return a ModelAndView with parameters as follow:
return new ModelAndView("redirect:/check/process?phone_number="+yourPhoneNumber+"&amount="+amount)

You can use forward to go to a new controller right?
"forward:/test2?param1=foo&param2=bar";
Please see below link for more details.
Spring forward with added parameters?

Related

ModelAndView and ModelMap in Spring MVC

#RequestMapping(value = "/testmap", method = RequestMethod.GET)
public ModelAndView testmap(ModelAndView model) {
ModelMap map=new ModelMap();
String greetings = "Greetings, Spring MVC! testinggg";
model.setViewName("welcome");
map.addAttribute("message", greetings);
return model;
}
I had
${message}
on welcome.jsp. But it does not prints the greetings.
Can you tell me the reason?
Model is an Interface. It defines a holder for model attributes and is primarily designed for adding attributes to the model. It contains four addAttribute (Overloaded) and one mergeAttributes and one containsAttribute method.
Example:
#GetMapping("/showViewPage")
public String passParametersWithModel(Model model) {
Map<String, String> map = new HashMap<>();
map.put("spring", "mvc");
model.addAttribute("message", "Baeldung");
model.mergeAttributes(map);
return "viewPage";
}
ModelAndView is a class which allows us to pass all the information required by Spring MVC (Model and View) in one return.
Example :
#GetMapping("/goToViewPage")
public ModelAndView passParametersWithModelAndView() {
ModelAndView modelAndView = new ModelAndView("viewPage");
modelAndView.addObject("message", "Baeldung");
return modelAndView;
}
Hope you get some clarity from this.

Spring MVC, call Controller if the word mentioned in the RequestMapping matches in the URL

Is it possible to call the Controller if the executed URL contains the word mentioned in the #RequestMapping of the respective Controller?
Here is my code
#Controller
#RequestMapping({"/employee","/nonemployee","/temp"})
public class EmployeeController {
#Autowired
EmployeeService service;
#RequestMapping("/add")
public ModelAndView employee() {
ModelAndView modelAndView = new ModelAndView("emp/add", "command", new Employee());
return modelAndView;
}
#RequestMapping("/employees")
public ModelAndView getEmployeeList() {
ModelAndView modelAndView = new ModelAndView("/emp/employees", "list", service.getEmployeeList());
return modelAndView;
}
#RequestMapping(value = "/create")
public String createEmployee(#ModelAttribute Employee employee, ModelMap model) {
service.newEmployee(employee);
model.addAttribute("name", employee.getName());
model.addAttribute("age", employee.getAge());
model.addAttribute("id", employee.getId());
return "/emp/create";
}
}
Using the above code with #RequestMapping({"/employee","/nonemployee","/temp"}) and #RequestMapping("/employees"), we can call the following urls, to list values:
http://localhost:8080/Spring/employee/employees
http://localhost:8080/Spring/nonemployee/employees
http://localhost:8080/Spring/temp/employees
On observing closely, we can see the matching word emp within all the three words/values passed to the RequestMapping. So, what I am looking for is the way using which the execution of Controller is occurred, if the URL contains the word emp.
On execution of the following URLs, list of values must be returned by the same method (getEmployeeList()), but without passing multiple or all the values to RequestMapping Annotation:
http://localhost:8080/Spring/employee/employees
http://localhost:8080/Spring/nonemployee/employees
http://localhost:8080/Spring/temp/employees
http://localhost:8080/Spring/exempt/employees
http://localhost:8080/Spring/attempt/employees
Change you Request Mapping to -
#RequestMapping("/*emp*")
This should work for what you want to do.

Signature of Methods Returning ModelAndView and Request Mapping by Method Name

Two beginner SpringMVC questions:
1) Are there required signature types in SpringMVC for ModelAndView-returning methods, or it's free-form, with whatever params/order you want? I've seen these examples:
public ModelAndView action1(HttpServletRequest request);
public ModelAndView action2(Model m);
public ModelAndView action2(HttpServletRequest request, Model m);
public ModelAndView action4();
//etc.
2) Is it possible to have a RequestMapping by method name, not the whole URL? We have a URL, /test, that can be either /test?method=action1 or /test?method=action2 (similar to Struts).
#RequestMapping("/test?method=action1")
public ModelAndView action1(Model m)
{
//...
}

How should I add attribute after redirect to a controller

I am just a newbie about Spring.
I am now using #ExceptionHandler to handle all the exception for my web application. And after I catch the exception, it will go to and error.jsp page displaying the error message.
I have a ParentController and in that, I have:
#org.springframework.web.bind.annotation.ExceptionHandler(PortalException.class)
public ModelAndView handle(PortalException e, HttpServletRequest request) {
ModelMap map = new ModelMap();
map.addAttribute("message", e.getMessage());
return new ModelAndView("/error", map);
}
and I have a ErrorControllerextends the ParentController to add the attributes:
#Controller
public class ErrorController extends ParentSecureController {
#RequestMapping(value = "/error", method = RequestMethod.POST)
#ResponseBody
public String errorHandler(Model model, HttpServletRequest request) {
model.addAttribute("excetpion.message", request.getParameter("message"));
return "/error";
}
}
In the error.jsp:
<p>Excpetion is: ${exception.message}</p>
When I run my application, I can catch the exception and jump to error.jsp, but no exception message is display.
Anyone can help me to figure out how to solve it.
Please try use:
#Controller
public class ErrorController extends ParentSecureController {
#RequestMapping(value = "/error", method = RequestMethod.POST)
#ResponseBody
public String errorHandler(Map<String, Object> map, HttpServletRequest request) {
map.put("excetpion.message", request.getParameter("message"));
return "/error";
}
}
UPDATE
Map you get it messae from #Controller to View in this case error.jsp
I hope these helped! :)

Override Generic Controller

I have the following function in my abstract controller
public abstract class GenericController<T extends PersistentObject> {
...
...
...
#RequestMapping(value = "/validation.json", method = RequestMethod.POST)
#ResponseBody
public ValidationResponse ajaxValidation(#Valid T t, BindingResult result) {
ValidationResponse res = new ValidationResponse();
if (!result.hasErrors()) {
res.setStatus("SUCCESS");
} else {
res.setStatus("FAIL");
List<FieldError> allErrors = result.getFieldErrors();
List<ErrorMessage> errorMesages = new ArrayList<ErrorMessage>();
for (FieldError objectError : allErrors) {
errorMesages.add(new ErrorMessage(objectError.getField(),
objectError.getDefaultMessage()));
}
res.setErrorMessageList(errorMesages);
}
return res;
}
At most cases the validation is sufficient for different kind of entities. Now I would like to customize the validation on my concrete controller as
#Controller
#RequestMapping("user")
public class UserController extends GenericController<User> {
#RequestMapping(value = "/validation.json", method = RequestMethod.POST)
#ResponseBody
public ValidationResponse ajaxValidation(#Valid User user,
BindingResult result, Locale locale) {
ValidationResponse res = super.ajaxValidation(user, result);
if (!user.getPassword().equals(user.getConfirmPassword())) {
res.setStatus("FAIL");
res.getErrorMessageList().add(
new ErrorMessage("confirmPassword", messageSource
.getMessage("password.mismatch", null, locale)));
}
return res;
}
}
With this I get the following error java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'userController' bean method. How can I solve this issue ? Is there a better approach ?
The problem here is that after extending your generic controller you have two different methods
public ValidationResponse ajaxValidation(#Valid T t, BindingResult result)
and
public ValidationResponse ajaxValidation(#Valid User user,
BindingResult result, Locale locale)
with the exact same mapping
user/validation.json
An ugly solution would be to add the Locale locale param to your abstract controller method (even if you don't use it) and add the #Overwrite annotation to the UserController method (you'll get a compilation error otherwise). This way the two methods become one.
The generic controller is extended by other classes ? Then you will have two identical requestmappings.
Are you sure the UserController is correctly getting user prepend request mapping applied ? As this works :
#RequestMapping("test")
public class ExampleController extends AbstractController {
#RequestMapping(value = "/Home", method = RequestMethod.GET)
public String getHome(Model model) {
return "home";
}
with the same mapping in AbstractController
#RequestMapping(value = "/Home", method = RequestMethod.GET)
public String getHome(Model model) {
return "home";
}

Resources