Spring MVC - Submit Form 400 Error - spring

I'm just begin writing an application using Spring MVC. I have 2 entities, District & City. A City has many districts, and each district belongs to a city.
In district.jsp I declare a form, allowing user input of the district name and a selection box to choose the City it belongs to.
The District entity looks like this:
<form:form action="${aAction}" commandName="district">
<table>
<c:if test="${!empty district.districtName}">
<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="districtName">
<spring:message text="District Name"/>
</form:label>
</td>
<td>
<form:input path="districtName" />
</td>
</tr>
<tr>
<td>
<form:label path="belongToCity">
<spring:message text="Belong to City"/>
</form:label>
</td>
<td>
<c:if test="${!empty listCities}">
<form:select path="belongToCity" items="${listCities}" itemLabel="cityName" itemValue="id"></form:select>
</c:if>
</td>
</tr>
<tr>
<td colspan="2">
<c:if test="${!empty district.districtName}">
<input type="submit"
value="<spring:message text="Edit District"/>" />
</c:if>
<c:if test="${empty district.districtName}">
<input type="submit"
value="<spring:message text="Add District"/>" />
</c:if>
</td>
</tr>
</table>
</form:form>
In my district controller I declare add action.
#RequestMapping(value = {"/district/add"}, method = RequestMethod.POST)
public String addDistrict(#ModelAttribute("district") District p,Model model, BindingResult result) {
if(result.hasErrors()) {
return "district";
}
this.districtService.addDistrict(p);
return "district";
}
When I run my project, however, it shows a 400 error and the error message: "The request sent by the client was syntactically incorrect."
I suspect my form is wrong somewhere, maybe it is not able to post to controller processing. Could someone help me identify the issue?

Your BindingResult parameter should be adjacent to modelAttribute. Below should be method signature.
#RequestMapping(value = {"/district/add"}, method = RequestMethod.POST)
public String addDistrict(#ModelAttribute("district") District p, BindingResult result, Model model) {
if(result.hasErrors()) {
return "district";
}
this.districtService.addDistrict(p);
return "district";
}

Related

Neither BindingResult nor plain target object for bean name 'user' available as request attribute error

I am new on spring. I am just trying to create my own CRUD OneToMany project. I have user and course table in my database. Course table has user_id foreign key references user(id).
When user successfully logged into the page, homePage.jsp comes and user courses are listed. When we click "Add Course" button in homePage.jsp, course-form.jsp file comes and we should add course.
The problem is, when I try to add course, I lost my user modelAttribute because in this time another attribute is on process with spring mvc.
When addedCourse form action performed these error occurs,
Cannot invoke "com.veg.entity.User.addCourse(com.veg.entity.Course)" because "user" is null
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
My Controller,
#PostMapping("/showFormForAdd")
public String showFormForAdd(#ModelAttribute("user") User theUser, Model theModel) {
Course theCourse = new Course();
theCourse.setUser(theUser);
theModel.addAttribute("course", theCourse);
theModel.addAttribute("user", theUser);
return "course-form";
}
#PostMapping("addedCourse")
public String addedCourse(#ModelAttribute("course") Course theCourse, Model theModel) {
User user = theCourse.getUser();
userService.save(user, theCourse);
theModel.addAttribute("user", user);
return "homePage";
}
homePage.jsp
<p>Welcome ${user.username}</p>
<span>
<form:form action="showFormForAdd" modelAttribute="user" method="POST">
<form:hidden path="username"/>
<form:hidden path="password"/>
<input type="submit" value="Add Course" class="add-course"/>
</form:form>
</span>
<table>
<tbody>
<tr>
<th>Course id</th>
<th>Course title</th>
</tr>
<c:forEach var="temp" items="${user.courses}">
<tr>
<td> ${temp.id} </td>
<td> ${temp.title} </td>
</tr>
</c:forEach>
</tbody>
</table>
course-form.jsp
<p>Welcome ${user.username}</p>
<span>
<form:form action="loggedUser" modelAttribute="user" method="POST">
<form:hidden path="username"/>
<form:hidden path="password"/>
<input type="submit" value="Back to Course List" class="add-course"/>
</form:form>
</span>
<!-- In the below I lost my user modelAttribute because I should use course attribute -->
<form:form action="addedCourse" modelAttribute="course" method="POST">
<table>
<tbody>
<tr>
<td> Title </td>
<td> <form:input path="title"/> </td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Add Course" class="add-course"/>
</td>
</tr>
</tbody>
</table>
</form:form>
I have #Transactional in my service, #Repository in my DAO and there is no problem with sessionFactory.

org.apache.jasper.JasperException: An exception occurred processing [WEB-INF/views/person.jsp] at line [24]

Trying to run the code from https://www.journaldev.com/3531/spring-mvc-hibernate-mysql-integration-crud-example-tutorial. Add functionality and listing works.but updating the data causes JSP error.
below is the error log
org.apache.jasper.JasperException: An exception occurred processing [WEB- INF/views/person.jsp] at line [24]
22: <form:form action="${addAction}" commandName="person">
23: <table>
24: <c:if test="${!empty person.name}">
25: <tr>
26: <td>
27: <form:label path="id">
Root Cause
java.lang.NumberFormatException: For input string: "name"
java.lang.NumberFormatException.forInputString(Unknown Source)
java.lang.Integer.parseInt(Unknown Source)
I'm not much experienced in JSP.so could'nt pin point to a particular point,tried many solutions and think seems to be in passing input to the field name.
My SQL table is named Person and is as given below
id int(11) PRIMARY Key auto_increment
name varchar(20)
country varchar(20)
Below is my complete JSP code for my form.
<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>
<form:label path="country">
<spring:message text="Country"/>
</form:label>
</td>
<td>
<form:input path="country" />
</td>
</tr>
<tr>
<td colspan="2">
<c:if test="${!empty person.name}">
<input type="submit"
value="<spring:message text="Edit Person"/>" />
</c:if>
<c:if test="${empty person.name}">
<input type="submit"
value="<spring:message text="Add Person"/>" />
</c:if>
</td>
</tr>
Looks like you are sending a Object[] instead of your Person object.
Read more here Getting NumberFormatException while getting the value in JSP using JSTL
To fix it, before adding the attribute to the request, ensure you are passing the correct object type (Person)
final TypedQuery<Person> query = entityManager.createQuery("SELECT person.name from Person person", Person.class);
final List<Person> resultList = query.getResultList();
Person person = resultList.get(0);
map.addAttribute("person", person);
if this does not help, post your backend code

How to know from which jsp page the request has come to the controller in Spring MVC

I am developing an app where LoginForm.jsp and UserRegistration.jsp will lead to UserAccount jsp page on specific action.In LoginForm when a user presses a 'Login' button ->UserAccount form is displayed.In UserRegistration Form when details are entered and submitted ->UserAccount form is displayed.
Below is the controller code when a request comes as UserAccount.html
#RequestMapping(value="/UserAccount.html", method = RequestMethod.POST)
public ModelAndView userAccountForm(#Valid #ModelAttribute("user") UserDetails user,BindingResult result) {
if(result.hasErrors())
{ System.out.println(result.getAllErrors());
ModelAndView model1=new ModelAndView("UserRegistration");
return model1;
}
// User validation
System.out.println(user.getAccountType());
userDAO.create(user);
ModelAndView model1 = new ModelAndView("UserAccount");
return model1;
}
LoginForm.jsp
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<body>
<h1
style="background-color: green; color: Yellow; padding: 10px; text-align: center;">Mybank
Online Login</h1>
<form:errors path="user.*" />
<form action="/MyBankProject/UserAccount.html" method="post">
<div
style="background-color: yellow; color: black; padding: 10px; text-align: center;"
align="center">
<p>
User ID <input type="text" name="userName" />
</p>
<p>
Password <input type="password" name="password" />
</p>
<input type="submit" value="Login" /> New User?
</div>
<input type="hidden" name="page" value="LoginForm"/>
</form>
</body>
</html>
UserRegistration.jsp
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<body>
<h1>${headerMessage}</h1>
<h3>USER REGISTRATION</h3>
<form:errors path="user.*" />
<form action="/MyBankProject/UserAccount.html" method="post">
<table border="1" style="width:100%" >
<tr>
<td>FirstName :</td>
<td><input type="text" name="firstName" /></td>
</tr>
<tr>
<td>LastName :</td>
<td><input type="text" name="lastName" /></td>
</tr>
<tr>
<td>User's EmailId :</td>
<td><input type="text" name="emailId" /></td>
</tr>
<tr>
<td>user's gender :</td>
<td><select name="gender" multiple>
<option value="M">Male</option>
<option value="F">Female</option>
</select></td>
</tr>
<tr>
<td>user's age :</td>
<td><input type="text" name="age" /></td>
</tr>
<tr>
<td>user's DOB :</td>
<td><input type="text" name="dOB" /></td>
</tr>
<tr>
<td>Account Type :</td>
<td><select name="accountType" multiple>
<option value="Savings">Savings</option>
<option value="Current">Current</option>
<option value="FixedDeposit">Fixed Deposit</option>
</select>
<td>
</tr>
<tr>
<td>Amount :</td>
<td><input type="text" name="amount" /></td>
</tr>
</table>
<table>
<tr>
<td>UserName</td>
<td><input type="text" name="userName" /></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password" /></td>
</tr>
</table>
<table>
<tr>
<td>User's Address :</td>
</tr>
<tr>
<td>country: <input type="text" name="address.country" /></td>
<td>city: <input type="text" name="address.city" /></td>
<td>street: <input type="text" name="address.street" /></td>
<td>pincode:<input type="text" name="address.pincode" /></td>
</tr>
<tr>
<td><button type="submit">Submit</button></td>
<td><input type="button" onclick="history.back();"
value="Cancel"></td>
</tr>
</table>
<input type="hidden" name="page" value="UserRegistration"/>
</form>
</body>
</html>
Now for me I need to know the jsp page from which the UserAccount invoked ,to perform different actions based on that.
I am new to Spring MVC and searched all over the internet for the solution.
HTTP is a stateless protocol. This means that you can not make assumptions about previous states.
I think you have two options to get information about the previous page anyways.
Add a hidden field to your form and send the name of the page with the request.
HTML:
<form>
<input type="hidden" name="page" value="[the name of the current page]"/>
</form>
Controller:
#RequestMapping(value="/UserAccount.html", method = RequestMethod.POST)
public ModelAndView userAccountForm(#RequestParam(value="page", required=false) String page) {
[...]
}
Now you can check the page value.
Use the session. Store the current page in the controller methods that render the form:
#RequestMapping("/login")
public String login(HttpServletRequest request) {
request.getSession().setAttribute("lastPage", "login");
return "redirect:/UserAccount.html";
}
#RequestMapping("/register")
public String register(HttpServletRequest request) {
request.getSession().setAttribute("lastPage", "register");
return "redirect:/UserAccount.html";
}
Check the lastPage value in userAccountForm():
#RequestMapping(value="/UserAccount.html", method = RequestMethod.POST)
public ModelAndView userAccountForm(HttpServletRequest request) {
HttpSession session = request.getSession();
String lastPage = (String) session.getAttribute("lastPage");
session.removeAttribute("lastPage");
[...]
}
Check the referer field of the request header.
#RequestMapping(value="/UserAccount.html", method = RequestMethod.POST)
public ModelAndView userAccountForm(#RequestHeader(value = "referer", required = false) String referer) {
[...]
}
This gives you the referer as a method argument if there is one. Be careful. It is possible that there was no referer or that the field was manipulated by the client.
Hope this will solve your need.
URL url = new URL(request.getHeader("referer"));
System.out.println("last page url"+ url.getPath());
if(url.getPath().equals("your last url"){
//code
}

Implementing Forgot password in Spring giving garbage URL

I am working on a Spring-MVC application. I want to implement the forgot password functionality. For that, I am using the secret question method. I have created a JSP page, where I recieve the values like username, secretanswer and then I check if the values exist and then save the new password which the user has given. I am having a problem wiht the JSP page, when I click submit, it shows me some garbage URL. I believe it is some tiny mistake, I am unable to see. Kindly let me know what is going wrong.
Apache tomcat error URL :
HTTP Status 404 - /id=0,%20username=null,%20password=null
Controller function for changing password :
#RequestMapping(value = "/forgotpassword")
public String forgotPassword(Model model){
model.addAttribute("person",new Person());
return "forgotpassword";
}
#RequestMapping(value = "/changepassword")
public String changepassword(#ModelAttribute("person") Person f,Model model){
System.out.println("Did we reach here on submit");
personService.checkAuthenticitiy(f.getUsername(), f.getSecretanswer(), f.getNewpassword());
model.addAttribute("person", new Person());
return "redirect:/forgotpassword";
}
JSP page :
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Forgot Passsword page</title>
</head>
<body>
<td><a href="<c:url value='/' />" >Go Home</a></td>
<h1>
Change password
</h1>
<c:url var="addAction" value="/changepassword" ></c:url>
<form:form action="${person}" commandName="person">
<table>
<tr>
<td>
<form:label path="username">
<spring:message text="username"/>
</form:label>
</td>
<td>
<form:input path="username" />
</td>
</tr>
<tr>
<td>
<form:label path="secretquestion" >
<spring:message text="secretquestion"/>
</form:label>
</td>
<td>
<form:input path="secretquestion"/>
</td>
</tr>
<tr>
<td>
<form:label path="secretanswer" >
<spring:message text="secretanswer"/>
</form:label>
</td>
<td>
<form:input path="secretanswer"/>
</td>
</tr>
<tr>
<td>
<form:label path="newpassword" >
<spring:message text="newpassword"/>
</form:label>
</td>
<td>
<form:input path="newpassword"/>
</td>
</tr>
<tr>
<td>
<input name="submit" type="submit" value="Submit" />
</td>
</tr>
</table>
</form:form>
</body>
</html>
Person model :
#Entity
#Table(name="person")
public class Person implements UserDetails{
#Column(name = "username")
private String username;
#Column(name = "password")
private String password;
#Column(name = "secretquestion")
private String secretquestion;
#Column(name = "secretanswer")
private String secretanswer;
#Transient
private String newpassword;
//Getters and setters for all.
}
<c:url var="addAction" value="/changepassword" ></c:url>
<form:form action="${person}" commandName="person">
should be
<c:url var="addAction" value="/changepassword" ></c:url>
<form:form action="${addAction}" commandName="person">
person is not your action

Spring-MVC model updating only after page refresh

I am working on a spring-mvc project which adds notes using a JSP file. Right now, all CRUD operations work in the project. The only problem is to see the updated information in the database, I have to hit refresh browser button everytime. I checked flashattributes, but as I am not redirecting, just returning the object, I don't find that useful. I am posting my controller code along with JSP code. Any ideas why I need to hit refresh.
P.S : Refresh is not necessary for delete function, and yes, I tried using redirect already for other functions.
COntroller code :
#RequestMapping(value= "/note/add")
public String addNote(#ModelAttribute("notices") Notes p,Model model) {
Person person = personService.getCurrentlyAuthenticatedUser();
model.addAttribute("notices", new Notes());
model.addAttribute("listNotes",this.notesService.listNotes());
model.addAttribute("listNotes", this.notesService.listNotePerson(person));
model.addAttribute("section1",this.notesService.listNotesBySectionId(1,person));
model.addAttribute("section2",this.notesService.listNotesBySectionId(2,person));
model.addAttribute("section3",this.notesService.listNotesBySectionId(3,person));
}
#RequestMapping("/editnote/{id}")
public String editNote(#PathVariable("id") Integer id, Model model){
Person person = personService.getCurrentlyAuthenticatedUser();
model.addAttribute("notices", this.notesService.getNoteById(id));
model.addAttribute("section1",this.notesService.listNotesBySectionId(1,person));
model.addAttribute("section2",this.notesService.listNotesBySectionId(2,person));
model.addAttribute("section3",this.notesService.listNotesBySectionId(3,person));
}
#RequestMapping(value = "/note/listing", method=RequestMethod.GET)
public String listNotices(Model model) {
Person person = personService.getCurrentlyAuthenticatedUser();
model.addAttribute("notices",new Notes());
model.addAttribute("listNotes", this.notesService.listNotePerson(person));
model.addAttribute("section1",this.notesService.listNotesBySectionId(1,person));
model.addAttribute("section2",this.notesService.listNotesBySectionId(2,person));
model.addAttribute("section3",this.notesService.listNotesBySectionId(3,person));
}
JSP code :
<c:url var="addAction" value="/note/add" ></c:url>
<form:form action="${addAction}" commandName="notices">
<table>
<c:if test="${!empty notices.notetext}">
<tr>
<td>
<form:label path="noticesid">
<spring:message text="noticesid"/>
</form:label>
</td>
<td>
<form:input path="noticesid" readonly="true" size="8" disabled="true" />
<form:hidden path="noticesid" />
</td>
</tr>
</c:if>
<tr>
<td>
<form:label path="notetext">
<spring:message text="notetext"/>
</form:label>
</td>
<td>
<form:input path="notetext" />
</td>
</tr>
<tr>
<td>
<form:label path="notetag" >
<spring:message text="notetag"/>
</form:label>
</td>
<td>
<form:input path="notetag"/>
</td>
</tr>
<tr>
<td>
<form:label path="notecolor">
<spring:message text="notecolor"/>
</form:label>
</td>
<td>
<form:input path="notecolor" />
</td>
</tr>
<tr>
<td>
<form:label path="canvasid">
<spring:message text="canvasid"/>
</form:label>
</td>
<td>
<form:input path="canvasid" />
</td>
</tr>
<tr>
<td>
<form:label path="sectionid">
<spring:message text="sectionid"/>
</form:label>
</td>
<td>
<form:input path="sectionid" />
</td>
</tr>
<tr>
<td>
<form:label path="canvasnName">
<spring:message text="canvasnName"/>
</form:label>
</td>
<td>
<form:input path="canvasnName" />
</td>
</tr>
<tr>
<td colspan="2">
<c:if test="${!empty notices.noticesid}">
<input type="submit"
value="<spring:message text="Edit note"/>" />
</c:if>
<c:if test="${empty notices.notetext}">
<input type="submit"
value="<spring:message text="Add note"/>" />
</c:if>
</td>
</tr>
</table>
</form:form>
<br>
<h3>Notes List</h3>
<c:url var="listAction" value="/note/listing" ></c:url>
<form:form action="${section1}" commandName="notices" method="post"> // Same code with section2 and section3
<c:if test="${!empty notices.noticesid}">
<table class="tg">
<tr>
<th width="80">Notes ID</th>
<th width="120">Notes text</th>
<th width="120">Note Tag</th>
<th width="120">Note color</th>
<th width="120">Note section</th>
<th width="120">Canvas id</th>
<th width="120">Canvas name</th>
<th width="120">Other id</th>
<th width="60">Edit</th>
<th width="60">Delete</th>
</tr>
<c:forEach items="${section1}" var="notices">
<tr>
<td>${notices.noticesid}</td>
<td>${notices.notetext}</td>
<td>${notices.notetag}</td>
<td>${notices.notecolor}</td>
<td>${notices.sectionid}</td>
<td>${notices.canvasid}</td>
<td>${notices.canvasnName}</td>
<td>${notices.personid}</td>
<td><a href="<c:url value='/editnote/${notices.noticesid}' />" >Edit</a></td>
<td><a href="<c:url value='/removenote/${notices.noticesid}' />" >Delete</a></td>
</tr>
</c:forEach>
</table>
</c:if>
</form:form>
So I was able to solve it finally by calling return "redirect:/note/listing" at end of/note/add function.
To be completely clear on this answer, simply create:
ModelAndView controller, and at the end of your controller, please, add:
ModelAndView mv = new ModelAndView("redirect:/note/listing");
return mv;

Resources