Spring-boot BindingResult not getting errors - spring

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.

Related

Filter data in spring boot

Dont know if this is possible but I want to call my data and filter it , so for example notification type will be for example 1 or 2 and then give me everything with a 1 and a 2
My Model
public class Notifications {
#Id
private String id;
private String notificationMsg;
private String notificationType;
private Date createdDate = new Date();
//Get all Notification by type
#RequestMapping(value = "/all/{notificationType}", method = RequestMethod.GET)
public List<Notifications> getAllByNotificationType(#PathVariable("notificationType") String notificationType) {
List<Notifications> notifications= this.notificationRepository.findByNotificationType(notificationType);
return user;
}
Or should I add to the model and create a interface like this
List<Notifications> findByNumber1ORNumber2ORNumber3(String Number1,String Number2,String Number3);
You can use in clause :
https://javadeveloperzone.com/spring/spring-jpa-query-in-clause-example/
List<Employee> findByEmployeeNameIn(List<String> names);

Spring boot application not accepting ID of incoming POST request

I have an existing system that uses string based unique IDs for users and I want to transfer that System into a Spring boot application. I want to creat a user so I send a POST request with the following content:
As you can see, the id gets ignored.
This is my Spring code for the user class:
#PostMapping("/user")
ResponseEntity addUser(User receivedUser) {
Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
logger.info("Empfangener User: " + receivedUser.toString());
try {
User mailCheckUser = userService.getUserByMail(receivedUser.getEmail());
User nameCheckUser = userService.getUserByName(receivedUser.getUsername());
if (mailCheckUser != null){
return new ResponseEntity("Email already exists", HttpStatus.NOT_ACCEPTABLE);
}
if (nameCheckUser != null){
return new ResponseEntity("Username already exists", HttpStatus.NOT_ACCEPTABLE);
}
userService.addUser(receivedUser);
} catch (Exception userCreationError) {
return new ResponseEntity(receivedUser, HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity(receivedUser, HttpStatus.OK);
}
public void addUser(User user) {
userRepository.save(user);
}
And this is my user class:
#Entity
#Table
public class User {
#Id
#Column(unique =true)
private String id;
private #Column(unique =true)
String username;
private #Column(unique =true)
String email;
private #Column(unique =true)
String simpleAuthToken;
private
String password;
/*REDACTED*/
private
boolean isBlocked;
public User(String id, String name, String email, boolean isBlocked) {
this.id = id;
this.username = name;
this.email = email;
this.simpleAuthToken = simpleAuthToken;
this.isBlocked = false;
}
public User() {
}
/*GETTERS AND SETTERS ARE HERE, BUT I CUT THEM FOR SPACING REASONS*/
}
And this is the Spring Output:
My expected outcome would be that Spring would recognize the id and then create a user with the id I provided. Why is the id always null?
EDIT: If I put the ID in a Put or Get Mapping as Path variable, like so:
#PutMapping("/user/{id}")
ResponseEntity updateUser(#PathVariable String id, User receivedUser) {}
then it gets read and recognized, but it will still be null in the receivedUser
First add #RequestBody in the post request body. In the Post request (/test/user) your passing some params but in the method level not received.
If you want receive id from postman then add #RequestParam("id")String id in the method level.
How you generating unique Id by manually or some generators?
And double check user id at the database console level.

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

Spring form validation error

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.

How to return a list of object as Json in Spring MVC

I'm trying to get a list of objects to render on a Spring 3 MVC app and would like to do this via Ajax.
So in my Spring class I have:
#RequestMapping(value = "/viewSearchEnquiriesAjax", method = RequestMethod.GET, headers = "Accept=application/json")
public #ResponseBody List<Enquiry> getEnquiriesBySearchAjax(#RequestParam String name) {
Search search = new Search();
search.setFirstName(name);
return searchEnquiries(search);
}
But I get a 500 (Internal Server Error) when this is run. This manifests itself when I'm debugging in the browser as 'GET http://localhost:8080/SpringMVC/viewSearchEnquiriesAjax?name=peter 500 (Internal Server Error)'
I can successfully return a single object with no error. Can the Spring Json mapper(Jackson) convert correctly? Am I missing something fundamental?
My javascript is as follows:
function doAjaxPost() {
// get the form values
var firstName = $('#firstName').val();
$.getJSON("/SpringMVC/viewSearchEnquiriesAjax", { name: firstName }, function(result) {
alert("Success");
});
}
My Enquiry object is an Entity:
#Entity
#Table(name = "enquiries")
public class Enquiry implements java.io.Serializable{
private static final long serialVersionUID = -5093725544297637792L;
protected Long id;
protected Date created = new Date();
...
...
public Enquiry() {
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", unique = true, nullable = false)
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
...
...
For Jackson you have to create a strongly typed list class because of type erasure:
public class EnquiryList extends ArrayList<Enquiry> {
}
Then return this list from your controller:
#RequestMapping(value = "/viewSearchEnquiriesAjax", method = RequestMethod.GET, headers = "Accept=application/json")
public #ResponseBody EnquiryList getEnquiriesBySearchAjax(#RequestParam String name) {
EnquiryList list = new EnquiryList();
...
return list;
}
Also check out this answer on a similar question.

Resources