I want to return multiple views(jsp) from one controller. i.e. one view below another
#RequestMapping(method = RequestMethod.GET, value = "register")
public String addUser(Model model) {
// on some condition
if(){
//add "user/login" above or below "user/edit"
}
model.addAttribute(new User());
return "user/edit";
}
i want to do this on controller not on jsp
it can be possible or i have to use tiles for it
You can only return one view. If you do not want to use a templating library then you need to set some model attribute and then use that to conditionally render some additional HTML.
CONTROLLER
#RequestMapping(method = RequestMethod.GET, value = "register")
public String addUser(Model model) {
if(x){
model.addAttribute("showAdditionalFields", true);
}
model.addAttribute(new User());
return "user/edit";
}
JSP
<c:if test="${showAdditionalFields}">
<!-- include here -->
</c:if>
Related
I am using Spring MVC for developing the Java Web Application.
In my current scenario, i am stuck in one situation.
In my current project, I have a dropdown and i need to pass the selected value on onChange to controller for processing the result.
For showing dropdown i am using form:select (Spring Form).
Can you please suggest me how to pass selected value to controller on OnChange
<body>
<form:form method="post" modelAttribute="ad" action="/save">
<form:select cssClass="select" cssStyle="width:100%;margin-left:10%;"
path="work_type" items="${allworktype}" itemValue="id"
itemLabel="work_type" />
</form:form>
#Controller
public class WebController {
#Autowired
public AdminBuildingRepo adminBuildingRepo;
#ModelAttribute("allworktype")
public List<AdminBuilding> getblocks(Model model){
return adminBuildingRepo.findAll();
}
#GetMapping("/")
public String home(Model model) {
AdminBuilding ad= new AdminBuilding();
model.addAttribute("ad", ad);
return "index";
}
#RequestMapping(value = "/save", method = RequestMethod.GET)
public String transferForDevice( Model model) throws Exception {
System.out.println("*********");
//so now I can use "user" from #ModelAttribute
return "redirect:/admin";
}
}
Please help me how to pass value to controller on selection.
function formSubmit(){
$('form#myForm').attr({action: 'save'});
$('form#myForm').attr({modelAttribute: 'ad'});
$('form#myForm').attr({method: 'post'});
$('form#myForm').submit();
}
declare form with id myForm
call this function on select onchange
I have two different jsp pages one is login.jsp and form.jsp.i want to build application like ones login success then form page will open. here i am handle two jsp pages but it will show ambiguity problem.
#RequestMapping(value = "/", method = RequestMethod.GET)
public String loginModel(Model model){
model.addAttribute("loginBean",new LoginBean());
return "login";
}
#RequestMapping(value = "/", method = RequestMethod.GET)
public String model(Model model){
//FrontBean fBean=new FrontBean();
model.addAttribute("frontBean",new FrontBean());
return "form";
}
Here is your login page, it is your welcome page also
#RequestMapping(value = "/", method = RequestMethod.GET)
public String loginModel(Model model) {
model.addAttribute("loginBean", new LoginBean());
return "login";
}
then you should not add the same path to another method. change your other method to like this (change the mapping value to the second method)
#RequestMapping(value = "/welcome", method = RequestMethod.GET)
public String model(Model model){
//FrontBean fBean=new FrontBean();
model.addAttribute("frontBean",new FrontBean());
return "form";
}
You also need business logic to check the username and password. thereafter redirect to your welcome page like this. (your login.jsp should send the username and password to /check-user in post method)
#PostMapping("/check-user")
String checkUser(#RequestParam("userName") String userName , #RequestParam("passWord") String passWord){
if(userName.equals("Your username") && passWord.equals("Your password")){
return "redirect:welcome";
}
return "error";
}
Remember this is not a secure way to implement. it is just an example of an easy understanding. you can implement your own things. best of luck
I have a simple variable declared in my jsp page
<html>
<body>
<c:set var="vehicle" scope="request" value="Car" />
<td>Cars</td>
</body>
</html>
I'm trying to access the variable vehicle with a value of "Car" in my Spring controller
#RequestMapping(value = "/vehicles", method = RequestMethod.GET)
public ModelAndView viewLaptops(#RequestParam(value = "vehicle", required = false) String vehicleType) {
if (vehicleType.equals("Car")) {
// retrieve car list, return the model for car list
}
else if (vehicleType.equals("Truck")) {
// retrieve truck list, return the model for truck list
}
System.out.println(carType);
}
but I'm getting a null value. How can I achieve this one? Thank you for any help.
Try updating the generated url as follows:
<c:set var="vehiculeURL">
<c:url value="productsHome/vehicles">
<c:param name="vehicle" value="Car"/>
</c:url>
</set>
Car
To pass values to your .jsp from a spring controller you use the Model parameter to you function:
#RequestMapping(value = "/vehicles", method = RequestMethod.GET)
public String viewLaptops(Model model, ...) {
model.addAttribute("Car", "Toyota");
return "index.jsp"; //path to your file
}
The you will have the value "Toyota" in your jsp with key "Car" by using the following syntax:
<div>${Car}</div>
I manage to solve everything that I want to happen, Using the #PathVariable, I am able to map multiple url request in a single controller, assuming I have 3 href
<td>Cars</td>
<td>Trucks</td>
<td>Bike</td>
I added another handler-method in my controller class that will support my default mapping with /vehicle
#RequestMapping(value = "/vehicles", method = RequestMethod.GET)
public ModelAndView viewVehicles() {
ModelAndView mv = new ModelAndView();
mv.setViewName("vehiclesPage");
return mv;
}
#RequestMapping(value = "/vechicles/{type}", method = RequestMethod.GET)
public ModelAndView viewDifferentVehicles(#PathVariable("type") String type) {
ModelAndView mv = new ModelAndView();
if(type.equals("Car") {
mv.setViewName("cars"); // cars.jsp
}
else if (type.equals("Truck") {
mv.setViewName("trucks"); // trucks.jsp
}
else if (type.equals("Bike") {
mv.setViewName("bikes"); //bikes.jsp
}
return mv;
}
This is exactly what I want to happen, mapping different request and returning the desired view in a single handler method, I thought accessing a JSP variable with some if-else structure will solve my problem, just some random luck I stumbled upon #PathVariable
I have a controller method with RequestMapping.PUT and having a URI
#RequestMapping(value = "/add/email", method = RequestMethod.POST)
public String addNewAccountEmail(#Valid #ModelAttribute EmailClass emailObject, BindingResult bindingResult, Model model) {
return displayForm(model);
}
I have a form like :
<form:form id="add-user-email" action="/add/email" name="manageUserAddEmail" method="post" modelAttribute="accountEmail">
I want to have more form pointing to same action , but need to do different operations inside addNewAccountEmail method. So how can I achieve this in Spring ? Basically any parameter which can make me differentiate functionalities or somehow I can have multiple methods having same RequestMapping URL and Method ?
I can only use RequestMethod.POST as I have similar requirements for other methods as well.
Basically I do not want the URL to change in Browser when invoking actions, that is why I want all form actions to point to same action URL.
You could point all of your forms at the same controller method and then differentiate the form-specific functionality within that method by looking for form-specific request parameters.
Each form would need to add its own request parameter to identify it - such as:
<input type="hidden" name="form1_param" value="1"/>
And then you can vary the behaviour inside the method by inspecting the HttpServletRequest:
#RequestMapping(value = "/add/email", method = RequestMethod.POST, )
public String addNewAccountEmail(#Valid #ModelAttribute EmailClass emailObject, BindingResult bindingResult, Model model, HttpServletRequest request) {
if (request.getParameter("form1_param") != null) { // identifies 1st form
// Do something
} else if (request.getParameter("form2_param") != null) { // indentifies 2nd form
// Do something else
}
...
}
It would be cleaner however to have multiple controller methods mapped to the same path, but specify different params in the RequestMapping - to differentiate the different forms.
#RequestMapping(value = "/add/email", params="form1_param", method = RequestMethod.POST)
public String addNewAccountEmail1(#Valid #ModelAttribute EmailClass emailObject, BindingResult bindingResult, Model model) {
// Do something specific for form1
return displayForm(model);
}
And also:
#RequestMapping(value = "/add/email", params="form2_param", method = RequestMethod.POST)
public String addNewAccountEmail2(#Valid #ModelAttribute EmailClass emailObject, BindingResult bindingResult, Model model) {
// Do something specific for form2
return displayForm(model);
}
Etc.
#RequestMapping accepts arrays as parameters (with an or semantic).
#RequestMapping(
value = "/add/email",
method = { RequestMethod.POST, RequestMethod.PUT } )
I have form object that I set to request in GET request handler in my Spring controller. First time user enters to page, a new form object should be made and set to request. If user sends form, then form object is populated from request and now form object has all user givern attributes. Then form is validated and if validation is ok, then form is saved to database. If form is not validated, I want to save form object to session and then redirect to GET request handling page. When request is redirected to GET handler, then it should check if session contains form object.
I have figured out that there is #SessionAttributes("form") annotation in Spring, but for some reason following doesnt work, because at first time, session attribute form is null and it gives error:
org.springframework.web.HttpSessionRequiredException: Session attribute 'form' required - not found in session
Here is my controller:
#RequestMapping(value="form", method=RequestMethod.GET)
public ModelAndView viewForm(#ModelAttribute("form") Form form) {
ModelAndView mav = new ModelAndView("form");
if(form == null) form = new Form();
mav.addObject("form", form);
return mav;
}
#RequestMapping(value="form", method=RequestMethod.POST)
#Transactional(readOnly = true)
public ModelAndView saveForm(#ModelAttribute("form") Form form) {
FormUtils.populate(form, request);
if(form.validate())
{
formDao.save();
}
else
{
return viewForm(form);
}
return null;
}
It throws Exception if controller called first time even though added #SessionAttributes({"form"}) to class. So add following populateForm method will fix this.
#SessionAttributes({"form"})
#Controller
public class MyController {
#ModelAttribute("form")
public Form populateForm() {
return new Form(); // populates form for the first time if its null
}
#RequestMapping(value="form", method=RequestMethod.GET)
public ModelAndView viewForm(#ModelAttribute("form") Form form) {
ModelAndView mav = new ModelAndView("form");
if(form == null) form = new Form();
mav.addObject("form", form);
return mav;
}
#RequestMapping(value="form", method=RequestMethod.POST)
#Transactional(readOnly = true)
public ModelAndView saveForm(#ModelAttribute("form") Form form) {
// ..etc etc
}
}
The job of #SessionAttribute is to bind an existing model object to the session. If it doesn't yet exist, you need to define it. It's unnecessarily confusing, in my opinion, but try something like this:
#SessionAttributes({"form"})
#Controller
public class MyController {
#RequestMapping(value="form", method=RequestMethod.GET)
public ModelAndView viewForm(#ModelAttribute("form") Form form) {
ModelAndView mav = new ModelAndView("form");
if(form == null) form = new Form();
mav.addObject("form", form);
return mav;
}
#RequestMapping(value="form", method=RequestMethod.POST)
#Transactional(readOnly = true)
public ModelAndView saveForm(#ModelAttribute("form") Form form) {
// ..etc etc
}
}
Note that the #SessionAttributes is declared on the class, rather than the method. You can put wherever you like, really, but I think it makes more sense on the class.
The documentation on this could be much clearer, in my opinion.
if there is no defined session object so I think it's gonna be like this:
#SessionAttributes({"form"})
#Controller
public class MyController {
#RequestMapping(value="form", method=RequestMethod.GET)
public ModelAndView viewForm() {
ModelAndView mav = new ModelAndView("form");
if(form == null) form = new Form();
mav.addObject("form", form);
return mav;
}
#RequestMapping(value="form", method=RequestMethod.POST)
#Transactional(readOnly = true)
public ModelAndView saveForm(#ModelAttribute("form") Form form) {
// ..etc etc
}
}
#Controller
#SessionAttributes("goal")
public class GoalController {
#RequestMapping(value = "/addGoal", method = RequestMethod.GET)
public String addGoal(Model model) {
model.addAttribute("goal", new Goal(11));
return "addGoal";
}
#RequestMapping(value = "/addGoal", method = RequestMethod.POST)
public String addGoalMinutes(#ModelAttribute("goal") Goal goal) {
System.out.println("goal minutes " + goal.getMinutes());
return "addMinutes";
}
}
On page addGoal.jsp user enters any amount and submits page. Posted amount is stored in HTTP Session because of
#ModelAttribute("goal") Goal goal
and
#SessionAttributes("goal")
Without #ModelAttribute("goal") amount entered by user on addGoal page would be lost
I'm struggling with this as well. I read this post and it made some things clearer:
Set session variable spring mvc 3
As far as I understood it this basically says:
that Spring puts the objects specified by #SessionAttributes into the session only for the duration between the first GET request and the POST request that comes after it. After that the object is removed from the session. I tried it in a small application and it approved the statement.
So if you want to have objects that last longer throughout multiple GET and POST requests you will have to add them manually to the HttpSession, as usual.