javaspringspring-bootvalidation

Spring boot validation error request bad 400


I'm developing a crud API with a post method, when testing this method in my postman it returns the error

2023-02-15T13:34:35.528-03:00  WARN 8792 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<java.lang.Object> com.api.order_control.controllers.OrderController.saveOrder(com.api.order_control.dtos.OrderDto) with 2 errors: [Field error in object 'orderDto' on field 'doorNumber': rejected value [null]; codes [NotBlank.orderDto.doorNumber,NotBlank.doorNumber,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [orderDto.doorNumber,doorNumber]; arguments []; default message [doorNumber]]; default message [must not be blank]] [Field error in object 'orderDto' on field 'block': rejected value [null]; codes [NotBlank.orderDto.block,NotBlank.block,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [orderDto.block,block]; arguments []; default message [block]]; default message [must not be blank]] ]

I couldn't understand why my blank cannot work with this method and why this error. can anybody help me?

model

package com.api.order_control.models;

import jakarta.persistence.*;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.UUID;

@Entity
@Table(name = "restaurant_orders")
public class OrderModel implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID id;
    @Column(nullable = false, length = 11)
    private String customerName;
    @Column(nullable = false, length = 15)
    private String phoneNumber;
    @Column(nullable = false, length = 25)
    private String address;
    @Column(nullable = false, length = 10)
    private String doorNumber;
    @Column(length = 5)
    private String block;
    @Column(nullable = false, length = 30)
    private String orderNote;
    @Column(nullable = false)
    private Float price;
    @Column(nullable = false)
    private LocalDateTime registrationDate;

    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getDoorNumber() {
        return doorNumber;
    }

    public void setDoorNumber(String doorNumber) {
        this.doorNumber = doorNumber;
    }

    public String getBlock() {
        return block;
    }

    public void setBlock(String block) {
        this.block = block;
    }

    public String getOrderNote() {
        return orderNote;
    }

    public void setOrderNote(String order) {
        this.orderNote = orderNote;
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    public LocalDateTime getRegistrationDate() {
        return registrationDate;
    }

    public void setRegistrationDate(LocalDateTime registrationDate) {
        this.registrationDate = registrationDate;
    }
}

dto pack

package com.api.order_control.dtos;

import jakarta.validation.constraints.NotBlank;

public class OrderDto {
    @NotBlank
    private String customerName;
    @NotBlank
    private String phoneNumber;
    @NotBlank
    private String address;
    @NotBlank
    private String doorNumber;
    @NotBlank
    private String block;
    @NotBlank
    private String orderNote;

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String doorNumber() {
        return doorNumber;
    }

    public void doorNumber(String doorName) {
        this.doorNumber = doorName;
    }

    public String getBlock() {
        return block;
    }

    public void setBlock(String block) {
        this.block = block;
    }

    public String getOrderNote() {
        return orderNote;
    }

    public void setOrderNote(String orderNote) {
        this.orderNote = orderNote;
    }

}

controller with post

package com.api.order_control.controllers;


import com.api.order_control.dtos.OrderDto;
import com.api.order_control.models.OrderModel;
import com.api.order_control.services.OrderService;
import jakarta.validation.Valid;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.ZoneId;

@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
@RequestMapping("/orders")
public class OrderController {

    final OrderService orderService;

    public OrderController(OrderService orderService) {
        this.orderService = orderService;
    }

    @PostMapping
    public ResponseEntity<Object> saveOrder(@RequestBody @Valid OrderDto orderDto) {
        var orderModel = new OrderModel();
        BeanUtils.copyProperties(orderDto, orderModel);
        orderModel.setRegistrationDate(LocalDateTime.now(ZoneId.of("UTC")));
        orderModel.setPrice(70.8f);
        return ResponseEntity.status(HttpStatus.CREATED).body(orderService.save(orderModel));
    }
}

I had already had a blank error because I was using a float, but in this case "numberDoor" is just a string. What is the reason for this error?

Postman request

{
    "customerName": "Ryan",
    "phoneNumber": "1 99859 5854",
    "address": "St Street Vl 190",
    "doorNumber": "5",
    "orderNote": "Pepperoni Pizza"
}

Solution

  • It's a validation error.

    1. You don't pass block in your post method, but in DTO this field annotated with @NotBlack
    2. You didn't provide eligible setter for doorNumber. As a result, this field is null in your DTO object, but again, is annotated with @NotBlack. The setter name must be setDoorNumber(String value) for that field