I am facing currently a huge issue : I can not retrieve date input by user in JSP page.
JSP code :
<form:form method="POST" action="myAction">
<tr><td>Date</td>
<td>
<spring:nestedPath path="myClasse.startDate" >
<input type="text" name="startDate" value="<c:out value="${status.value}"/> "/></spring:nestedPath>
</td></tr>
I input date in all existing forms. my code part corresponding to the retrieval of startDate in the Controller:
System.out.println("date: " + myClasse.getStartDate());
give me null
Here are some details that can help :
I have this in my model class :
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "start_date", length = 19)
public Date getStartDate()
{
return this.startDate;
}
public void setStartDate(Date startDate)
{
this.startDate = startDate;
}
Service class :
session.createQuery("SELECT DISTINCT name where startDate=:startDate").setParameter("startDate", "startDate");
I found a solution that can fix this problem :
In my controller class I added this :
#InitBinder
public void initBinder(WebDataBinder binder)
{
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
Hope that will help people facing this issue :)
Related
I have problem with this code...
<form action="#" th:action="#{'/portfolio/' + ${portfolios.getId()} + '/old' }" th:object="${Date}" method="post">
<table>
<tr>
<td>From: <input type="date" th:value="*{date_a}" th:field="*{date_a}" /></td>
</tr>
<tr>
<td><input type="submit" th:onclick="'javascript:loading()'" value="Change day" /></td>
</tr>
</table>
I really dont get why this is not working...
Its copy paste from other pages, which there are 3 of, and all the others are okey with this same snippet. But here i get error.
org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "date_a" (template: "portfolio" - line 12, col 42)
i pass an empty object on previous page with
ThymeDate date = new ThymeDate();
modelAndView.addObject("Date", date);
EDIT:
ThymeDate
#Entity
#Table(name = "dto_thyme")
public class ThymeDate implements Serializable {
#Id
#GeneratedValue
long id;
#DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate date_a;
#DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate date_b;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public LocalDate getDate_a() {
return date_a;
}
public void setDate_a(LocalDate date_a) {
this.date_a = date_a;
}
public LocalDate getDate_b() {
return date_b;
}
public void setDate_b(LocalDate date_b) {
this.date_b = date_b;
}
public ThymeDate() {
}
public ThymeDate(LocalDate date_a, LocalDate date_b) {
this.date_a = date_a;
this.date_b = date_b;
}
}
I still dont know if this about reserved keyword or something like that...
changed form object name from Date to ThymeDate and now it works?
if anyone have better explanation i can accept that as answer...
I'm in the process of learning spring and thymeleaf and working on a timekeeping project.
For this I need to validate the number of hours an employee clocks in one day.
I used the tutorial in the spring documentation for this however i keep getting the following error
Neither BindingResult nor plain target object for bean name 'timetable' available as request attribute
Any ideas what I might be doing wrong?
Controller class
#RequestMapping(value="Timetable/AddToTimetable", method = RequestMethod.GET)
public String newUser(Model md) {
md.addAttribute("assignments", serv.findAll());
return "AddToTimetable";
}
#RequestMapping(value = "/createEntry", method = RequestMethod.POST)
public String create(#RequestParam("assignmentId") int assignmentId,
#RequestParam("date") #DateTimeFormat(pattern = "yyyy-MM-dd") Date date,
#RequestParam("hoursWorked") int hoursWorked,
#Valid Timetable timetable, BindingResult bindingResult,
Model md) {
timetable = new Timetable();
timetable.setAssignmentId(assignmentId);
timetable.setDate(date);
timetable.setHoursWorked(hoursWorked);
md.addAttribute("timetables", service.timetableAdd(timetable));
if (bindingResult.hasErrors()) {
return "AddToTimetable";
}
return "redirect:/Timetable";
}
Service class
public BigInteger timetableAdd(Timetable timetable){
KeyHolder keyHolder = new GeneratedKeyHolder();
String sql = "INSERT INTO timetables ( assignmentId, date, hoursWorked) VALUES ( ?, ?, ?)";
template.update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement pst = con.prepareStatement(sql, new String[] {"id"});
pst.setInt(1, timetable.getAssignmentId());
pst.setDate(2, new java.sql.Date(timetable.getDate().getTime()));
pst.setInt(3, timetable.getHoursWorked());
return pst;
}
}, keyHolder);
return (BigInteger) keyHolder.getKey();
}
}
Model class
package ro.database.jdbcPontaj.model;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.Date;
public class Timetable {
private int timetableId;
private int assignmentId;
private Date date;
private String project;
#NotNull
#Min(0)
#Max(12)
private int hoursWorked;
public int getTimetableId() {
return timetableId;
}
public void setTimetableId(int timetableId) {
this.timetableId = timetableId;
}
public int getAssignmentId() {
return assignmentId;
}
public void setAssignmentId(int assignmentId) {
this.assignmentId = assignmentId;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public int getHoursWorked() {
return hoursWorked;
}
public void setHoursWorked(int hoursWorked) {
this.hoursWorked = hoursWorked;
}
public String getProject() {
return project;
}
public void setProject(String project) {
this.project = project;
}
public Timetable() {
}
public Timetable(int timetableId, String project, Date date, int hoursWorked) {
this.timetableId = timetableId;
this.project=project;
this.date = date;
this.hoursWorked = hoursWorked;
}
public Timetable(int timetableId, int assignmentId, Date date, int hoursWorked) {
this.timetableId = timetableId;
this.assignmentId = assignmentId;
this.date = date;
this.hoursWorked = hoursWorked;
}
}
Html
<form method="post" name="comment_form" id="comment_form" th:action="#{/createEntry}" th:object="${timetable}" role="form">
<p> Project</p><br>
<select name="assignmentId">
<option value="" th:each="assignment: ${assignments}" th:value="${assignment.assignmentId}" th:text="${assignment.assignmentId}"></option>
</select>
<p>Date</p> <br>
<input class="datepicker" type="text" name="date"><br>
<p>Number of hours</p>
<input type="text" name="hoursWorked" th:field="*{hoursWorked}"><br>
<p th:if="${#fields.hasErrors('hoursWorked')}" th:errors="*{hoursWorked}">Age Error</p>
<button type="submit" id="submit" class="btn btn-primary">Submit</button>
</form>
UPDATE:
Timetable (skipping bootstrap divs)
<div class="row">
<div class="col-md-10 title">
<h2>Timetable</h2>
</div>
<div class="col-md-2">
</div>
<div class="col-md-12">
<table class="table table-bordered">
<thead>
<tr>
<th>id</th>
<th>assignment</th>
<th>date</th>
<th>number of hours</th>
</tr>
</thead>
<tbody>
<tr th:each = "timetable: ${timetables}">
<td th:text="${timetable.timetableId}">45</td>
<td th:text="${timetable.project}">vasi</td>
<td th:text="${timetable.date}">1 ian</td>
<td th:text="${timetable.hoursWorked}">3000</td>
</tr>
</tbody>
</table>
Service method for Timetable
#Autowired
JdbcTemplate template;
public List<Timetable> findAll(String loginname) {
String sql = " SELECT timetables.timetableId, timetables.assignmentId, timetables.date, " +
"timetables.hoursWorked, users.username, projects.projectName AS project " +
"FROM timetables INNER join assignments on timetables.assignmentId = assignments.assignmentId " +
"INNER JOIN projects on assignments.projectId = projects.projectId " +
"INNER JOIN users on users.userId = assignments.userId where username= ?";
RowMapper<Timetable> rm = new RowMapper<Timetable>() {
#Override
public Timetable mapRow(ResultSet resultSet, int i) throws SQLException {
Timetable timetable = new Timetable(resultSet.getInt("timetableId"),
resultSet.getString("project"),
resultSet.getDate("date"),
resultSet.getInt("hoursWorked"));
return timetable;
}
};
return template.query(sql, rm, loginname);
}
The controller method for Timetable
#RequestMapping(value = {"/Timetable"}, method = RequestMethod.GET)
public String index(Model md){
org.springframework.security.core.Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String loginname = auth.getName();
md.addAttribute("timetables", service.findAll(loginname));
return "Timetable";
}
If I understand correctly you have two html pages one that shows all the assignments and one that you enter the new entry.I think that get the error when there is a validation error in the new entry page.
Substitute these lines
if (bindingResult.hasErrors()) {
return "AddToTimetable";
}
with these ones
if (bindingResult.hasErrors()) {
return "newEntry";//replace the newentry with the html page that you enter the new entry
}
When there is an error, you should go to the page that you tried to enter the new entry and not in the page that has all the assignments.
I am trying to pass the resume back to the Spring MVC controller. I have created a user class that saves resume/files
public class User {
private int id;
private String firstName;
private String lastName;
private String city;
private String state;
private String zip;
private String username;
private String password;
private int enabled;
private byte[] resume;
//getters/setters for them all
and the controller to take in the uploaded form from the site
#Controller
#RequestMapping(value = "/user")
public class UserController {
UserDao uDao;
#Inject
public UserController(UserDao uDao) {
this.uDao = uDao;
}
#RequestMapping(value = "/profile", method = RequestMethod.GET)
public String postPage(Principal principal, Map model) {
String name = principal.getName();
User u = uDao.getByUsername(name);
String fName = u.getFirstName();
String lName = u.getLastName();
String city = u.getCity();
String state = u.getState();
String zip = u.getZip();
String bc = u.getBootcampAttended();
model.put("fName", fName);
model.put("lName", lName);
model.put("city", city);
model.put("state", state);
model.put("zip", zip);
model.put("bc", bc);
return "user";
}
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String Upload(#RequestParam("file") MultipartFile file, Principal principal) throws IOException {
if (!file.isEmpty()) {
byte[] bytes = file.getBytes(); // alternatively, file.getInputStream();
// application logic
String name = principal.getName();
User u = uDao.getByUsername(name);
u.setResume(bytes);
uDao.update(u);
return "user";
}
return "user";
}
}
I am trying to pass the resume to display as a clickable file on the jsp in the postPage method. Here is the jsp
<h1>${fName}</h1>
<h1>${lName}</h1>
<h1>${state}</h1>
<h1>${city}</h1>
<h1>${zip}</h1>
<h1>${bc}</h1>
<form method="POST" action="${pageContext.request.contextPath}/user/upload" enctype="multipart/form-data">
<table border="0">
<tr>
<td>Pick file #1:</td>
<td><input type="file" name="file" size="50" /></td>
<td><input type="submit" value="Upload"/>
</tr>
</table>
</form>
Any tips on how to get the file on the Spring MVC controller. Preferably to be the value of the file input as default, instead of it saying "No File Chosen". Was thinking that maybe I could convert the file back into the MultiPartFile, like how I uploaded it, but im not sure how to pass that back to the Spring MVC controller.
Thanks!
Controller class-
#Controller
#SessionAttributes({"id", "roleId"})
#RequestMapping("/User")
public class UserController {
#Autowired
private UserService userv = null;
#InitBinder("stdUser")
private void initBinder(WebDataBinder binder) {
System.out.println("1111======"+binder.getObjectName());
binder.setValidator(new NewUserValidator());
System.out.println("2222======"+binder.getObjectName());
}
#RequestMapping(value = "/allUsers")
public ModelAndView allUser(#ModelAttribute("userSetup")#Valid UserBean stdUser, BindingResult result, Map<String, Object> map, HttpSession session) {
StdCheckAccessV chk = new StdCheckAccessV();
chk.setFexe(Screens.User.substring(Screens.User.lastIndexOf("/") + 1, Screens.User.length()));
chk.setUid(Long.parseLong(session.getAttribute("id").toString().trim()));
chk.setRid(Long.parseLong(session.getAttribute("roleId").toString().trim()));
chk = userv.getAccess(chk);
List<StdUsers> l = userv.getUsersList();
stdUser.setChkAccessV(chk);
map.put("userList", l);
return new ModelAndView(Screens.User);
}
#RequestMapping(value = "/submitUser")
public ModelAndView addOrUpdate(#ModelAttribute("userSetup")#Valid UserBean stdUser, BindingResult result, HttpSession session, final RedirectAttributes redA) {
try {
int res = 0;
Long id = stdUser.getStdUsers().getId();
if (result.hasErrors()) {
System.out.println("///////result has errors " + result.toString());
return new ModelAndView("redirect:/User/allUsers");
}
System.out.println("////////the id============"+id);
if (id == null) {
System.out.println("/////inside the if");
stdUser.getStdUsers().setUserGroupId(Long.parseLong(session.getAttribute("id").toString().trim()));
stdUser.getStdUsers().setCreatedBy(Long.parseLong(session.getAttribute("id").toString().trim()));
stdUser.getStdUsers().setCreationDate(new Date());
res = userv.submitUser(stdUser);
} else {
System.out.println("/////inside the else");
stdUser.getStdUsers().setUpdateDate(new Date());
stdUser.getStdUsers().setUpdatedBy(Long.parseLong(session.getAttribute("id").toString().trim()));
res = userv.updateUser(stdUser);
}
} catch (Exception e) {
System.out.println("////Exception in add or update method " + e);
}
return new ModelAndView("redirect:/User/allUsers");
//return "redirect:/User/allUsers";
}}
Validator class-
#Component
public class NewUserValidator implements Validator {
#Override
public boolean supports(Class<?> userOb) {
return UserBean.class.equals(userOb);
}
#Override
public void validate(Object target, Errors errors) {
try {
UserBean user = (UserBean) target;
if (user.getStdUsers().getUserName() == null) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "stdUsers.userName", "user.name.empty");
//errors.reject("stdUsers.userName", "User Name is mandatory");
}
} catch (Exception e) {
System.out.println(e);
}
}
}
Bean Class-
public class UserBean {
private #Valid StdUsers stdUsers;
private #Valid StdCheckAccessV chkAccessV;
private boolean listView = true;
private String rePassword;
getters and setters.... }
index.jsp-
<body>
<%
session.setAttribute("id", 1);
session.setAttribute("roleId", 1);
%>
User<br>
</body>
CMN/STD100002.jsp page
<td class="tdright"><form:label path="stdUsers.userName">User Name<em>*</em></form:label></td>
<td><form:input path="stdUsers.userName"/></td>
<td><form:errors path="stdUsers.userName"></form:errors></td>
<a href="#" name="btnsub" id="btnsub" onclick="submitUser()">
<table cellspacing="0" cellpadding="0" border="0">
<tr>
<td width="25" height="24px" align="center">
<img src="${pageContext.servletContext.contextPath}/resources/images/Buttons/gray icon/Add.png" width="16" height="15" border="0" />
</td>
<td>Submit</td>
<td></td>
</tr>
</table>
</a>
<script type="text/javascript">
function submitUser(){
document.form1.action="${pageContext.servletContext.contextPath}/User/submitUser";
document.form1.submit();
}
</script>
I am following a tutorial for using validation in spring as i am new for spring.
On click of the submit button while leaving the User Name field empty, it should get validated with the message from Validator.
When i tried to print the error in controller class by-
System.out.println("result has errors " + result.toString());
it prints-
result has errors org.springframework.validation.BeanPropertyBindingResult: 1 errors
Please help, i am not getting where i am wrong.
I used this code to check where is the error-
for (Object object : result.getAllErrors()) {
if (object instanceof FieldError) {
FieldError fieldError = (FieldError) object;
System.out.println("the field errors::::::::::::::::"+fieldError.getCode());
}
if (object instanceof ObjectError) {
ObjectError objectError = (ObjectError) object;
System.out.println("the object errors:::::::::"+objectError.getCode());
}
}
and i found-
the field errors::::::::::::::::user.name.empty
the object errors:::::::::user.name.empty
///////result has errors org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'userSetup' on field 'stdUsers.userName': rejected value []; codes [user.name.empty.userSetup.stdUsers.userName,user.name.empty.stdUsers.userName,user.name.em pty.userName,user.name.empty.java.lang.String,user.name.empty]; arguments []; default message [null]
Since these two fields i am putting empty to check validation. If i will get these error on putting the fields empty then how can i validate them?
StdUser-
#Entity
#Table(name = "STD_USERS")
#NamedQueries({
#NamedQuery(name = "StdUsers.findAll", query = "SELECT s FROM StdUsers s")})
public class StdUsers implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name="generator",strategy="increment")
#GeneratedValue(generator="generator")
#Basic(optional = false)
#Column(name = "ID", nullable = false)
private Long id;
#Basic(optional = false)
#Column(name = "USER_NAME", nullable = false, length = 50)
private String userName;
setters and getters.....
Any one please reply.
Oh finally got the solution just here-
Changed the Validator class as-
try {
UserBean user = (UserBean) target;
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "stdUsers.userName","required.stdUsers.userName" ,"User name required");
} catch (Exception e) {
System.out.println(e);
}
and in Controller class rather than returning to controller's allUsers method when result.hasError() i.e.-
return new ModelAndView("redirect:/User/allUsers");
changed to(navigated to page)-
return new ModelAndView("/CMN/STD100002");
and yes if you are getting date conversion related error, use this in your controller class-
#InitBinder
private void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");//edit for the format you need
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
I am trying to add form validations to a working application. I started by adding a NotNull check to Login Form. I am using Hibernate impl of Bean Validation api.
Here's the code I have written
#Controller
#RequestMapping(value="/login")
#Scope("request")
public class LoginController {
#Autowired
private CommonService commonService;
#Autowired
private SiteUser siteUser;
#InitBinder
private void dateBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
CustomDateEditor editor = new CustomDateEditor(dateFormat, true);
binder.registerCustomEditor(Date.class, editor);
}
#ModelAttribute
protected ModelMap setupForm(ModelMap modelMap) {
modelMap.addAttribute("siteUser", siteUser);
return modelMap;
}
#RequestMapping(value="/form", method = RequestMethod.GET)
public ModelAndView form(ModelMap map){
if (siteUser.getId() == null){
map.addAttribute("command",new SiteUser());
return new ModelAndView("login-form",map);
}else {
return new ModelAndView("redirect:/my-dashboard/"+siteUser.getId());
}
}
#RequestMapping(value="/submit", method=RequestMethod.POST)
public ModelAndView submit(#Valid SiteUser user, ModelMap map, BindingResult result){
if (result.hasErrors()) {
map.addAttribute("command", user);
System.out.println("Login Error block");
return new ModelAndView("login/form",map);
}
else {
User loggedInUser = commonService.login(user.getEmail(), user.getPassword());
if (loggedInUser != null) {
siteUser.setId(loggedInUser.getId());
siteUser.setName(loggedInUser.getName());
System.out.println("site user attr set");
}
return new ModelAndView("redirect:/my-dashboard/"+loggedInUser.getId());
}
}
}
The Model is
#Component
#Scope("session")
public class SiteUser {
private Integer id = null;
#NotNull
private String name = null;
private String email = null;
private String password = null;
private List<String> displayPrivList = null;
private List<String> functionPrivList = null;
// And the getters and setters
}
The JSP is
<c:url var="loginSubmitUrl" value="/login/submit"/>
<form:form method="POST" action="${loginSubmitUrl}">
<form:errors path="*" />
<div class="row">
<div class="span4">
</div>
<div class="span4">
<h3>Please Login</h3>
<label><span style="color:red">*</span>Email</Label><form:input path="email" type="text" class="input-medium" />
<label><span style="color:red">*</span>Password</Label><form:input path="password" type="password" class="input-medium" />
<br/>
<button type="submit" class="btn btn-primary">Login</button>
<button type="button" class="btn">Cancel</button>
</div>
</div>
</form:form>
I have added messages.properties and the annotation driven bean def in the context xml.
Other answers on the subject talk about form fields not getting posted. In my case, that's the expected behavior - that if I submit a blank form, I should get an error.
Please advise what am I missing?
I think this question had the same issue as yours
Syntactically incorrect request sent upon submitting form with invalid data in Spring MVC (which uses hibernate Validator)
which just points out
You have to modify the order of your arguments. Put the BindingResult result parameter always directly after the parameter with the #Value annotation
You need this: <form:errors path="email" cssClass="errors" />
Use the tag form:errors for each input with the same "path" name.
It is also possible to list all the error at the same time if you don't put a path.
Here, check an full example with sample code that you can download to learn how to do:
http://www.mkyong.com/spring-mvc/spring-3-mvc-and-jsr303-valid-example/
Can you try changing the <form:form> by including the commandName to it like this
<form:form method="POST" action="${loginSubmitUrl}" commandName="user">