Spring form validation error - spring

my spring mvc application has a form input box when i validate input using v form validatio it throw errors on server...
And i have set error message on messages.properties file also.
error
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.validation.ConstraintViolationException: validation failed for classes [com.company.product.domain.Rating] during persist time for groups [javax.validation.groups.Default, ]
Rating Domain
#Entity
#Table(name = "rating")
public class Rating {
int id;
#NotEmpty
String name;
Date createdDate;
boolean isDelete;
getter,setter
}
in my domain i set validation for one field-"name"
controller
#RequestMapping(value = "/add-rating")
public String addRating(#ModelAttribute(value = "rating") Rating rating,BindingResult result) {
if(result.hasErrors()){
return "/secure/admin/rating";
}
java.util.Date utilDate = new java.util.Date();
Date sqlDate = new Date(utilDate.getTime());
rating.setCreatedDate(sqlDate);
ratingService.saveRating(rating);
return "redirect:/rating";
}
Why is not validating form error??

You have not instructed Spring to run the validation process.
In order to do that you need to add #Valid
#RequestMapping(value = "/add-rating")
public String addRating(#Valid #ModelAttribute(value = "rating") Rating rating,BindingResult result) {
if(result.hasErrors()){
return "/secure/admin/rating";
}
java.util.Date utilDate = new java.util.Date();
Date sqlDate = new Date(utilDate.getTime());
rating.setCreatedDate(sqlDate);
ratingService.saveRating(rating);
return "redirect:/rating";
}
Check out this tutorial for more information.

Related

Spring-boot BindingResult not getting errors

My BindingResult is not getting the errors but they appear on the stack trace.
My sales has a regex pattern for salesno:
#Entity
public class Sale {
public Sale() {
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotEmpty
#Pattern(regexp = "^S\\d{9}$", message = "Sales number must be in the format S123456789")
private String salesno;
The DTO backing the html for uses SalesViewDTO
public class SaleViewModel {
private Sale sale = new Sale();
And the controller:
#PostMapping("newSale")
public String saleSubmit(#Valid #ModelAttribute("SaleViewModel") SaleViewModel saleViewModel, BindingResult result) {
if (result.hasErrors()) {
List<ObjectError> errors = result.getAllErrors();
for(ObjectError error : errors) {
System.out.println("This is the error: " +error);
}
return "sale";
} else {
// Other stuff
If I then try to submit the form I get the message on console:
ConstraintViolationImpl{interpolatedMessage='Sales number must be in the format S123456789', propertyPath=salesno, rootBeanClass=class com.gmbh.domain.Sale, messageTemplate='Sale number must be in the format S123456789'}
I want to know why the Binding Result result is empty?
Add #Valid to the sale inner object of the SaleViewModel
public class SaleViewModel {
#Valid
private Sale sale = new Sale();
It's necessary to validate nested objects as well.

#requestparam value = date spring boot

#Controller
#RequestMapping(value="/reservations")
public class ReservationController {
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
#Autowired
private ReservationService reservationService;
#RequestMapping(method = RequestMethod.GET)
public String getReservation(#RequestParam(value="date", required=false) String dateString, Model model){
Date date = null;
if(dateString != null){
try {
date = DATE_FORMAT.parse(dateString);
} catch (ParseException pe) {
date = new Date();
}
}else{
date = new Date();
}
List<RoomReservation> roomReservationList = this.reservationService.getRoomReservationsForDate(date);
model.addAttribute("roomReservations", roomReservationList);
return "reservations";
}
}
I understand that the #RequestParam annotation is used to bind parameter values of query string to the controller method parameters. So for example, http://localhost:8080/reservations?date=2017-01-01. However, where does the value="date" come from? I dont see any value "date" inside my html page.
if you submit a form as method:"GET" (not POST) and form contains a input field named date then submitting this form will hit this handler method.

Error with JPA PagingAndSorting request parameter

I have a Controller that pages and sorts all the news in my database:
#RequestMapping(value = "/viewstatus", method = RequestMethod.GET)
ModelAndView viewStatus(ModelAndView modelAndView, #RequestParam(name = "p", defaultValue = "1") int pageNumber) {
Page<StatusUpdate> page = statusUpdateService.getPage(pageNumber);
modelAndView.getModel().put("page", page);
modelAndView.setViewName("app.viewStatus");
return modelAndView;
}
With its call to the service that works fine:
public Page<StatusUpdate> getPage(int pageNumber) {
PageRequest request = new PageRequest(pageNumber-1, pageSize, Sort.Direction.DESC, "added");
return statusUpdateDao.findAll(request);
}
But now, I would like to do the same SortingAndPaging BUT with one parameter (SiteUser). Here is my object:
#Entity
#Table(name = "status_update")
public class StatusUpdate {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Size(min=5, max=255, message="{addstatus.title.size}")
#Column(name = "title")
private String title;
#Size(min=5, max=5000, message="{addstatus.text.size}")
#Column(name = "text")
private String text;
#Column(name = "added")
#Temporal(TemporalType.TIMESTAMP)
#DateTimeFormat(pattern="yyyy/MM/dd hh:mm:ss")
private Date added;
#OneToOne(targetEntity = SiteUser.class)
#JoinColumn(name="user_id")
private SiteUser siteUser;
#PrePersist
protected void onCreate() {
if (added == null) {
added = new Date();
}
}
public StatusUpdate() {
}
But when I do it, it gives me this error:
Exception: org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [3] did not match expected type [com.caveofprogramming.model.entity.SiteUser (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [3] did not match expected type [com.caveofprogramming.model.entity.SiteUser (n/a)]
Failed URL: http://192.168.160.128:8080/viewmystatus
Exception message: Parameter value [3] did not match expected type [com.caveofprogramming.model.entity.SiteUser (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [3] did not match expected type [com.caveofprogramming.model.entity.SiteUser (n/a)]
I tired to send a String, but it did not work. I had to change it to a NativeQuery but I does not work with PagingAndSorting, it only works as a List (which is a headache to work with). So if you can help me with the ERROR of PagingAndSorting that would be great.
Here is the Controller:
#RequestMapping(value = "/viewmystatus", method = RequestMethod.GET)
ModelAndView viewMyStatus(ModelAndView modelAndView, #RequestParam(name = "p", defaultValue = "1") int pageNumber) {
SiteUser user = getUser();
Long user_id= user.getId();
Page<StatusUpdate> page = statusUpdateService.findMyStatusUpdates(user_id, pageNumber);
for(StatusUpdate statusUpdate: page){
SiteUser siteUser= statusUpdate.getSiteUser();
modelAndView.getModel().put("siteuser", siteUser);
}
modelAndView.getModel().put("page", page);
modelAndView.setViewName("app.viewStatus");
return modelAndView;
}
Here is the service:
public Page<StatusUpdate> findMyStatusUpdates(Long user_id, int pageNumber) {
PageRequest request = new PageRequest(pageNumber-1, pageSize, Sort.Direction.DESC, "added");
return statusUpdateDao.findBySiteUser(user_id, request);
}
And the DAO:
#Repository
public interface StatusUpdateDao extends PagingAndSortingRepository<StatusUpdate, Long> {
StatusUpdate findFirstByOrderByAddedDesc();
Page<StatusUpdate> findBySiteUser(Long user_id, Pageable pageable);
}
Thanks for your help!
Use a SiteUser object:
public Page<StatusUpdate> findMyStatusUpdates(Long user_id, int pageNumber) {
PageRequest request = new PageRequest(pageNumber-1, pageSize, Sort.Direction.DESC, "added");
return statusUpdateDao.findBySiteUser(new SiteUser(user_id), request);
}
You could try query by nested properties as well, but I think you must change user_id by userId, as underscore is a reserved character. Have a look to the documentation:
Spring data JPA Property expressions
Have you changed your findBySiteUser method? The one you posted looks fine but it seems is complaining about the signature. Even when PageRequest implements Pageable the signature has to be declared, explicitly, using Pageable, but the error message you are getting says PageRequest
public abstract org.springframework.data.domain.Page com.caveofprogramming.model.repository.StatusUpdateDao.findB‌​ySiteUser(com.caveof‌​programming.model.en‌​tity.SiteUser,org.sp‌​ringframework.data.d‌​omain.PageRequest)
More info:
PageRequest parameter not recognized as Pageable in Paging query

Unable to fix: 'java.lang.String' to required type 'java.util.Collection'

I'm getting this error when I submit my form and cannot figure out why this is happening. I believe the taglib should be handling this. I've tried changing the value passed in my jsp to itemValue="id" but it has no affect.
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'content' on field 'stateCollection': rejected value [com.myapp.cmt.model.State[ id=3 ]]; codes [typeMismatch.content.stateCollection,typeMismatch.stateCollection,typeMismatch.java.util.Collection,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [content.stateCollection,stateCollection]; arguments []; default message [stateCollection]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Collection' for property 'stateCollection'; nested exception is java.lang.IllegalStateException:
Cannot convert value of type [java.lang.String] to required type [com.myapp.cmt.model.State] for property 'stateCollection[0]': no matching editors or conversion strategy found]
My jsp
<strong>State</strong><br/>
<form:checkboxes path="stateCollection" items="${states}" itemLabel="name"/>
My Content
public class Content implements Serializable {
.......
#JoinTable(name = "content_to_state", joinColumns = {
#JoinColumn(name = "content_id", referencedColumnName = "id")}, inverseJoinColumns = {
#JoinColumn(name = "state_id", referencedColumnName = "id")})
#ManyToMany
private Collection<State> stateCollection;
.....
#XmlTransient
public Collection<State> getStateCollection() {
return stateCollection;
}
public void setStateCollection(Collection<State> stateCollection) {
this.stateCollection = stateCollection;
}
.....
My Controller
...
#RequestMapping(value = "/{guid}/save", method = RequestMethod.POST)
public ModelAndView saveContent(#ModelAttribute("content") Content content, #PathVariable("guid") String guid) {
try {
// Save the modified object
contentService.save(content);
} catch (IllegalOrphanException ex) {
...
My content service
...
#Transactional
public void save(Content content) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
try {
utx.begin();
em.merge(content);
utx.commit();
} catch (Exception ex) {
} finally {
if (em != null) {
em.close();
}
}
}
...
Your title isn't correct. You have declared a Collection<State> your input is a String. Spring couldn't know how to make a State from a String, you have to tell it. Please see this question: Converting from String to custom Object for Spring MVC form Data binding?
I had the same problem. i'm using Spring, Hibernate.
I have one class with composite primary key and pass two parameters in request, my mistake was:
#Entity
#Table(name = "TAREAS")
public class Tarea implements Serializable {
private static final long serialVersionUID = 1L;
protected TareaPK clave;
private String descripcion;
.....
}
the controller:
#RequestMapping(value = "/tareas", params = {"clave", "tipot"}, method = RequestMethod.GET)
public String formularioTareaEditar(
#RequestParam(value = "clave") String clave,
#RequestParam(value = "tipot") String tipoTrabajo,
Model model) {
Tarea tarea = catalogoService.getTarea(tipoTrabajo, clave);
model.addAttribute(tarea);
return "tarea/editar";
}
#RequestMapping(value = "/tareas", params = {"clave", "tipot"}, method = RequestMethod.POST)
public String tareaEditar(#Valid #ModelAttribute Tarea tarea, BindingResult result) {
if (result.hasErrors()) {
return "tarea/editar";
} else {
catalogoService.edit(tarea);
return "redirect:/tareas";
}
}
So... when the info gets in the controller the parameter clave is considered as if the object TareaPK of the primary key.
i just change the name of the parameter in my controller.
#RequestMapping(value = "/tareas", params = {"txt_clave", "tipot"}, method = RequestMethod.GET)
public String formularioTareaEditar(...){
...
}

Spring MVC : How to Validate Nested Bean Property with Ajax

Suppose that I have these classes :
class Child {
private int id;
#NotNull
#Size(min = 5)
private String name;
#NotNull
private Parent parent;
//getter and setter methods
}
class Parent {
private int id;
#NotNull
private String name;
//getter and setter methods
}
Here is the handler method:
#RequestMapping(value = "/add", method = RequestMethod.POST)
#ResponseBody
public Map<String, ?> add(#Valid Child child, BindingResult result) {
Map<String, ?> out = new LinkedHashMap<String, ?>();
if(result.hasErrors()){
Map<String, String> errors = new LinkedHashMap<String, String>();
for (FieldError error : result.getFieldErrors()) {
errors.put(error.getField(), error.getDefaultMessage());
}
out.put("success", false);
out.put("errors", errors);
return out;
} else {
out.put("success", true);
}
return out;
}
If I submit this data to add a child via Ajax (POST):
name = testtesttest
parent.id = 3
Everything is OK. The new child is saved successfully.
But If don't include the parent.id (only name is set)
name = testtesttest
The validation result return this:
"errors":{"parent":"may not be null"}
Note the "parent" property in that JSON. It's supposed to return parent.id not parent.
It causes problem as the field on client-side script (HTML) has the name parent.id not parent.
Any suggestion How to solve this??
Thank you.
NOTE:
If I change the submitted data to this:
name = testtesttest
parent = 3
I got the other error:
{"success":false,"errors":{"parent":"Failed to convert property value of type 'java.lang.String' to required type 'com.test.entity.Parent' for property 'parent'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.test.entity.Parent] for property 'parent': no matching editors or conversion strategy found"}}

Resources