How are Spring MVC Controllers being bound to JSP pages? - spring

Hi I am new to spring and I am trying to develop a simple portlet that accepts users first and last name and saves it to db using hibernate.
Basically I cannot figure out how the jsps and controllers communicate; I am missing some chunk here.
This is my first controller that needs to be called (where do I mention so?)
package codes.controller;
import javax.portlet.RenderResponse;
import codes.base.User;
import codes.service.UserService;
#Controller(value="SimpleUserController")
#RequestMapping(value = "VIEW")
public class SimpleUserController {
// -- auto-wiring of service dependency
#Autowired
#Qualifier("userService")
private UserService userService;
// --maps the incoming portlet request to this method
#RenderMapping
public String showUsers(RenderResponse response) {
return "home";
}
#ExceptionHandler({ Exception.class })
public String handleException() {
return "errorPage";
}
// -- #ModelAttribute here works as the referenceData method
#ModelAttribute(value="user")
public User getCommandObject() {
return new User();
}
}
Initially I am displaying a home.jsp that will display the form with two input boxes and a submit button.
<%#include file="include.jsp" %>
<portlet:actionURL var="addUserActionUrl">
<portlet:param name="myaction" value="addUser" />
</portlet:actionURL>
<form:form name="home" commandName="user" method="post"
action="${addUserActionUrl}">
<table>
<tr>
<td>First Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="firstname" /></td>
</tr>
<tr>
<td>Last Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="lastname" /></td>
</tr>
<table align="right">
<tr>
<td> </td>
<td><input type="submit" value="SUBMIT" /></td>
</tr>
</table>
</table>
</form:form>
This JSP should call the action method in the AddUserController.java:
package codes.controller;
import javax.portlet.ActionResponse;
import javax.portlet.RenderResponse;
import codes.base.User;
import codes.service.UserService;
#Controller(value = "AddUserController")
#RequestMapping(value = "VIEW")
public class AddUserController {
#Autowired
#Qualifier("userService")
private UserService userService;
#RenderMapping(params = "myaction=addUser")
public String showRegisterPage(Model model) {
model.addAttribute("user", new User());
model.addAttribute("users", getUsers());
return "addUser";
}
public List<User> getUsers() {
return userService.getAllUsers();
}
#ActionMapping(params = "myaction=addUser")
public void addBook(#ModelAttribute(value = "user") User user,
BindingResult bindingResult, ActionResponse response,
SessionStatus sessionStatus) {
if (!bindingResult.hasErrors()) {
userService.addUser(user);
response.setRenderParameter("myaction", "users");
sessionStatus.setComplete();
} else {
response.setRenderParameter("myaction", "addUser");
}
}
}
This time this firstname+last name should be saved in the db AND the screen should refresh to show a new form that will have a dropdown with the current users' names in the database and another first name and last name form fields. If you select a username from the dropdown the form fields are populated and you can edit these values and click on UPdate button to save the values in DB. Otherwise you can add a new user to the database using submit button.
addUser.jsp:
<%#include file="include.jsp" %>
<portlet:actionURL var="addUserActionUrl">
<portlet:param name="myaction" value="addUser" />
</portlet:actionURL>
<portlet:renderURL var="homeUrl">
<portlet:param name="myaction" value="Users" />
</portlet:renderURL>
<script type="text/javascript" src="js/userRelated.js"></script>
<form:form name="addUser" commandName="user" method="post"
action="${addUserActionUrl}">
<form:select path="model">
<form:option value="NONE" label="--- Select ---" id="userList" onchange="showHide()"/>
<form:options items="${users}" />
</form:select>
<table>
<tr>
<td>First Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="firstname" /></td>
</tr>
<tr>
<td>Last Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="lastname" /></td>
</tr>
<table align="right">
<tr>
<td> </td>
<td><input type="submit" id="submit" value="SUBMIT" />SUBMIT</td>
</tr>
<tr>
<td> </td>
<td><input type="submit" id="update" value="SUBMIT" />UPDATE</td>
</tr>
</table>
</table>
</form:form>
I am hiding and unhiding the SUBMIT/UPDATE button using onchange of dropdown. How do I call different functions in the addUsercontroller depending on the button available?

by updating the action attribute of form element with javascript

Related

Why Http status code 404 shows when I click on submit using war file deployed

Image 1. Successful GET request
Image 2. Failed POST when click on submit
Welcome page i.e. index.jsp aprears on localhost:8080/war_filename
but when we click on login in index page it shows http status code 404
Is anyone there, who's having the same issue?
I've copied the war file in apache\webapps
WebController.java
#Controller
public class indexController {
String errorMessage = "Invalid credentials";
#GetMapping("/login")
public String login() {
return "index.jsp";
}
/*********** Login using form ************/
#RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(#RequestParam("firstname") String firstName,
#RequestParam("lastname") String lastName) {
System.out.println("inside login form");
Customer object = repository.findByFirstNameAndLastName(firstName,
lastName);
if (object != null) {
return "home.jsp";
}
return "index.jsp";
}
}
index.jsp
<h3>Do Login Here</h3>
<form method="POST" action="/login">
<table>
<tr>
<td>Employee ID</td>
<td><input type="text" name="firstname" placeholder="Username" required></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="lastname" placeholder="Password" required></td>
</tr>
<tr>
<td><input type="submit" value="Login" /></td>
</tr>
</table>
</form>
home.jsp
<body>
<h3>Operations</h3>
<form action="/selectusingform" method="get">
Select
</form>
<table>
<tr>
<td>Insert</td>
</tr>
<tr>
<td>Update</td>
</tr>
<tr>
<td>Delete</td>
</tr>
<tr>
<td>Find</td>
</tr>
</table>

ModelAndView Spring

Details:
I am testing my first spring project , I am unable to get form data in backing bean . Here my code please help me execute this.
Welcome.jsp is my landing page from here I want to take userid and password and show in userInfo page.
Controller :--
package com.accounts.common.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
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 com.accounts.common.backingBean.LoginBackingBean;
/**
* Handles requests for the application welcome page.
*/
#Controller
public class WelcomeController {
/**
* Simply selects the welcome view to render by returning void and relying
* on the default request-to-view-translator.
*/
#RequestMapping(value= "/welcome" ,method = RequestMethod.GET)
**public ModelAndView welcome() {
return new ModelAndView("welcome", "userForm", new LoginBackingBean());
}**
#RequestMapping(value="/userInfo" ,method = RequestMethod.POST)
public String userInfo(#ModelAttribute("userForm")LoginBackingBean login ,
ModelMap model){
model.addAttribute("userId" , login.getUserId());
model.addAttribute("password" , login.getPassword());
return "userInfo";
}
}
Here is code for Welcome JSP :-- Only snapshot I am adding
<body>
<form id=login method="POST" action="/AccountingSW/userInfo" >
<div align="center">
<table>
<tr>
<td>User ID : </td>
<td> <input type="text"> </td>
</tr>
<tr>
<td>Password :</td>
<td><input type="password"> </td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value ="Login">
</td>
</tr>
<tr>
<td colspan="2" align="center">
<label style="font-size: 10;color: red">Already existing Member</label>
</td>
</tr>
<tr><td colspan="2" align="center">OR</td></tr>
<tr><td colspan="2" align="center">
<input type="submit" value ="SignUp"></td></tr>
<tr>
<td colspan="2" align="center">
<label style="font-size: 10;color: red">New Member</label>
</td>
</tr>
</table>
</div>
</form >
</body>
</html>
Here is code for UserInfo JSP :
I am putting only snapshot of what the jsp contains
<title>Hello ${userForm.userId}</title>
</head>
<body>
<h2>User Info</h2>
<table>
<tr>
<td>UserId</td>
<td>${userForm.userId}</td>
</tr>
<tr>
<td>Password</td>
<td>${userForm.password}</td>
</tr>
</table>
</body>
</html>
Here is code for Backing Bean :--
package com.accounts.common.backingBean;
public class LoginBackingBean {
private String userId;
private String password;
/* Getter and setters generated */
}
I am able to execute the jsp(s) but the userId and Password is not getting set
Please try to change from
public String userInfo(#ModelAttribute("userForm")LoginBackingBean login
to
public String userInfo(#ModelAttribute("loginBackingBean")LoginBackingBean login
as #ModelAttribute's document
The default model attribute name is inferred from the declared
attribute type (i.e. the method parameter type or method return type),
based on the non-qualified class name: e.g. "orderAddress" for class
"mypackage.OrderAddress", or "orderAddressList" for
"List".
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ModelAttribute.html#name--
In your welcome.jsp you are missing property name on inputs:
<td> <input type="text" name ="userId"> </td>
<td><input type="password" name="password"> </td>

Spring MVC Form Validation Neither BindingResult nor plain target object for bean name 'BanqueForm' available as request attribute

I have a probleme when validating a form with spring MVC
i have this exception
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'BanqueForm' available as request attribute
this is my controller
package org.gestion.banque.controllers;
import java.util.Map;
import javax.validation.Valid;
import org.gestion.banque.entities.Compte;
import org.gestion.banque.metier.IBanqueMetier;
#Controller
public class BanqueController {
#Autowired
private IBanqueMetier metier;
#RequestMapping(value="/index",method=RequestMethod.GET)
public String index(Model model){
model.addAttribute("BanqueForm", new BanqueForm());
return"banque";
}
#RequestMapping(value="/chargerCompte", method=RequestMethod.GET)
public String charger(Model m) {
m.addAttribute("BanqueForm", new BanqueForm());
return "banque";
}
#RequestMapping(value="/chargerCompte",method=RequestMethod.POST)
public String charger(#Valid BanqueForm bf,
BindingResult result,Model model){
if(result.hasErrors())
{
return "banque";
}
try {
Compte c=metier.ConsulterCompte(bf.getCode());
bf.setTypeCompte(c.getClass().getSimpleName());
bf.setCompte(c);
} catch (Exception e) {
bf.setException(e.getMessage());
}
model.addAttribute("BanqueForm", bf);
return "banque";
}
}
and this is my view
<body>
<div>
<f:form modelAttribute="BanqueForm" method="post" action="chargerCompte" >
<table>
<tr>
<td>Code :</td>
<td><f:input path="code"/></td>
<td><f:errors path="code"></f:errors> </td>
</tr>
<tr>
<td>
<input type="submit" value="OK" />
</td>
</tr>
</table>
</f:form>
</div>
<c:if test="${ not empty BanqueForm.exception}">
<div>${BanqueForm.exception} </div>
</c:if>
<c:if test="${not empty BanqueForm.compte}">
<div>
<table>
<tr>
<td>Solde :</td>
<td>${BanqueForm.compte.solde}</td>
</tr>
<tr>
<td>Solde :</td>
<td>${BanqueForm.compte.dateCreation}</td>
</tr>
<tr>
<td>Type de Compte :</td>
<td>${BanqueForm.typeCompte}</td>
</tr>
<c:if test="${BanqueForm.typeCompte=='CompteCourant'}">
<tr>
<td>Decouvert :</td>
<td>${BanqueForm.compte.decouvert}</td>
</tr>
</c:if>
<c:if test="${BanqueForm.typeCompte=='CompteEpargne'}">
<tr>
<td>taux :</td>
<td>${BanqueForm.compte.taux}</td>
</tr>
</c:if>
</table>
</div>
</c:if>
</body>
</html>
Add #ModelAttribute("BanqueForm") annotation when obtaining BanqueForm object. Something like this:
public String charger(#Valid #ModelAttribute("BanqueForm") BanqueForm bf,
BindingResult result, Model model) { ... }

Spring:Using Controller actions in one JSP file

I am working on a Spring-MVc project. I have a single JSP page, with two forms. Both these forms are handled by 2 different controllers, and they have separate database tables, seperate service methods. But I would like to individually select information(notes) which the user is adding and save them. I am posting both of my controller, JSP file, and the error message. Kindly let me know what might be going wrong. Thank you for your time.
PersonController :
#Controller
public class PersonController {
private PersonService personService;
#Autowired(required=true)
#Qualifier(value="personService")
public void setPersonService(PersonService ps){
this.personService = ps;
}
#RequestMapping(value = "/", method = RequestMethod.GET)
public String listPersons(Model model) {
model.addAttribute("person", new Person());
model.addAttribute("listPersons", this.personService.listPersons());
return "person";
}
//For add and update person both
#RequestMapping(value= "/person/add", method = RequestMethod.POST)
public String addPerson(#ModelAttribute("person") Person p){
//new person, add it
this.personService.addPerson(p);
return "redirect:/";
}
#RequestMapping("/remove/{id}")
public String removePerson(#PathVariable("id") String id){
this.personService.removePerson(id);
return "redirect:/persons";
}
#RequestMapping("/edit/{id}")
public String editPerson(#PathVariable("id") String id, Model model){
model.addAttribute("person", this.personService.getPersonById(id));
model.addAttribute("listPersons", this.personService.listPersons());
return "person";
}
}
keyactivitiesController.java
#Controller
public class KeyActivitiesController {
private KeyActivitiesService keyActivitiesService;
#Qualifier(value="keyActivitiesService")
public void setKeyActivitiesService(KeyActivitiesService keyActivitiesService){this.keyActivitiesService = keyActivitiesService;}
#RequestMapping(value = "/keynotice", method = RequestMethod.GET)
public String listNotices(Model model) {
model.addAttribute("keyactivities", new KeyActivities());
model.addAttribute("listNotices", this.keyActivitiesService.listNotices());
return "keyactivities";
}
//For add and update person both
#RequestMapping(value= "/keynotice/add", method = RequestMethod.POST)
public String addPerson(#ModelAttribute("keyactivities") KeyActivities p){
//new person, add it
this.keyActivitiesService.addKeyNotice(p);
return "redirect:/";
}
#RequestMapping("/removeNotice/{id}")
public String removePerson(#PathVariable("id") String id){
this.keyActivitiesService.removeNotice(id);
return "redirect:/";
}
#RequestMapping("/editNotice/{id}")
public String editPerson(#PathVariable("id") String id, Model model){
model.addAttribute("keyactivities", this.keyActivitiesService.getNoticenById(id));
model.addAttribute("keyactivities", this.keyActivitiesService.listNotices());
return "keyactivities";
}
}
person.jsp
<c:url var="addAction" value="/person/add" ></c:url>
<form:form action="${addAction}" commandName="person">
<table>
<c:if test="${!empty person.name}">
<tr>
<td>
<form:label path="id">
<spring:message text="ID"/>
</form:label>
</td>
<td>
<form:input path="id" readonly="true" size="8" disabled="true" />
<form:hidden path="id" />
</td>
</tr>
</c:if>
<tr>
<td>
<form:label path="name">
<spring:message text="Name"/>
</form:label>
</td>
<td>
<form:input path="name" />
</td>
</tr>
<tr>
<td colspan="1">
<c:if test="${!empty person.name}">
<input type="submit"
value="<spring:message text="Edit Notice"/>" />
</c:if>
<c:if test="${empty person.name}">
<input type="submit"
value="<spring:message text="Add Notice"/>" />
</c:if>
</td>
</tr>
</table>
</form:form>
<br>
<c:url var="addAction" value="/keynotice/add" ></c:url>
<form:form action="${addAction}" commandName="keyactivities">
<table>
<c:if test="${!empty keyactivities.keynotice}">
<tr>
<td>
<form:label path="id">
<spring:message text="ID"/>
</form:label>
</td>
<td>
<form:input path="id" readonly="true" size="8" disabled="true" />
<form:hidden path="id" />
</td>
</tr>
</c:if>
<tr>
<td>
<form:label path="keynotice">
<spring:message text="Keynotice"/>
</form:label>
</td>
<td>
<form:input path="keynotice" />
</td>
</tr>
<tr>
<td colspan="1">
<c:if test="${!empty keyactivities.keynotice}">
<input type="submit"
value="<spring:message text="Edit Notice"/>" />
</c:if>
<c:if test="${empty keyactivities.keynotice}">
<input type="submit"
value="<spring:message text="Add Notice"/>" />
</c:if>
</td>
</tr>
</table>
</form:form>
</body>
</html>
Error :
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'keyactivities' available as request attribute
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:144)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:168)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:188)
org.springframework.web.servlet.tags.form.LabelTag.autogenerateFor(LabelTag.java:130)
org.springframework.web.servlet.tags.form.LabelTag.resolveFor(LabelTag.java:120)
Stacktrace:
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:568)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:465)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:209)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:267)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1221)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1005)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:952)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
refactor this method:
#RequestMapping(value = "/", method = RequestMethod.GET)
public String listPersons(Model model) {
model.addAttribute("person", new Person());
model.addAttribute("keyactivities", new KeyActivities());
model.addAttribute("listPersons", this.personService.listPersons());
return "person";
}
The error is that after post either form, you will not have keyactivities in the model

Neither BindingResult nor plain target object for bean name 'command'. Spring exception

i'm starting learning spring MVC3, and i would like to display a simple "search form" here my jsp file
<form:form method="post" action="addGeo.html" >
<table>
<tr>
<td>
<input type="submit" value="<spring:message code="label.addzone"/>"/>
</td>
</tr>
</table>
</form:form>
<form:form method="post" action="maingeo.html" >
<table>
<tr>
<td>
<form:label path="codeZone"><spring:message code="label.area"/></form:label>
</td>
<td>
<form:input path="codeZone" />
</td>
<td>
<form:label path="type"><spring:message code="label.type"/></form:label>
</td>
<td>
<form:input path="type" />
</td>
<td>
<form:label path="codePostal"><spring:message code="label.departement"/></form:label>
</td>
<td>
<form:input path="codePostal" />
</td>
<td>
<input type="submit" value="<spring:message code="label.searchArea"/>"/>
</td>
</tr>
</table>
</form:form>
and here my controller :
#Controller
public class RefGeoController {
#Autowired
private RefGeoService refgeoService;
#RequestMapping("/maingeo")
public String goSearchArea() {
return "maingeo";
}
}
when i go to this url page, i've got this exception : java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute . I think that i forgot something in my form or maybe in my controller but i dont know where. Moreover what should i put on my method parameter when i don't want to send specific model to my jsp view?
You need to write an Class, that contains the fields of your form - this kind of class is called Command-Object/Class.
Then in your Controller method, that is responsible for providing the form page, you need to create an instance of this Command-Object, put it in the Model and then let the view render it. The name that is used for the Command-Object in the Model, must match the "command" attribute name of the <form:form command="myCommand"> tag. If you don't have this attribute, than the default name is command.
#Controller public class RefGeoController {
#Autowired private RefGeoService refgeoService;
#RequestMapping("/maingeo")
public ModelAndView goSearchArea() {
return new ModelAndView("maingeo", "searchCommand", new SearchCommand());
}
//only to prevent your next question: How to recive the committed form
#RequestMapping("/maingeo.html", method = RequestMethod.POST)
public ModelAndView handleSearch(SearchCommand searchCommand) {
... implement the search stuff
}
}
<form:form method="post" action="maingeo.html" command="searchCommand">

Resources