Quantcast
Channel: Active questions tagged rest - Stack Overflow
Viewing all articles
Browse latest Browse all 3744

Spring is not throwing MethodArgumentNotValidException when an invalid request body is sent to the restful service

$
0
0

I am working on an ecommerce backend. I have this CheckoutRestController class with this reserveCartItems(@RequestBody @Valid ReserveItemsRequest reserveItemsRequest) web service. I am sending a request to /api/v1/reserve-items with invalid values for some of the fields. In Postman I see the response status code as 400 Bad Request and response body as:

<!doctype html><html lang="en"><head><title>HTTP Status 400 – Bad Request</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 400 – Bad Request</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).</p><hr class="line" /><h3>Apache Tomcat/9.0.96</h3></body></html>

In pom.xml:

<dependencies><!-- Spring --><!--        https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.9</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-tx --><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.3.9</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-orm --><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>5.3.9</version></dependency><!-- Add Jackson for JSON converters --><!--        https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.5</version></dependency><!-- Hibernate --><!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core --><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>5.6.0.Final</version></dependency><!-- MySQL --><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.31</version></dependency><!-- C3PO --><!-- https://mvnrepository.com/artifact/com.mchange/c3p0 --><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version></dependency><!--        https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator --><dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>6.2.0.Final</version></dependency><!--        https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator-annotation-processor --><dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator-annotation-processor</artifactId><version>6.2.0.Final</version></dependency><!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency><!-- https://mvnrepository.com/artifact/redis.clients/jedis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>5.2.0</version></dependency></dependencies>

In CheckoutRestController.java:

@RestController@RequestMapping("/api")public class CheckoutRestController {    @Autowired    private CheckoutService checkoutService;    @PostMapping(path = "/v1/reserve-items", produces="application/json")    public ResponseEntity<ReserveItemsResponse> reserveCartItems(@RequestBody @Valid ReserveItemsRequest             reserveItemsRequest) {        ReserveItemsResponse reserveItemsResponse = checkoutService.reserveCartItems(reserveItemsRequest);        if(reserveItemsResponse.getReservationStatus() == ReservationStatus.Failed) {            return new ResponseEntity<ReserveItemsResponse>(reserveItemsResponse, HttpStatus.BAD_REQUEST);        }        return ResponseEntity.ok(reserveItemsResponse);    }}

In ReserveItemsRequest.java:

import java.util.List;import javax.validation.Valid;import javax.validation.constraints.NotNull;public class ReserveItemsRequest {    @NotNull(message = "User ID must not be null")    private Integer userId;    @Valid    @NotNull(message = "Cart items must not be null")    private List<CartItem> cartItems;    public ReserveItemsRequest() {    }    public Integer getUserId() {        return userId;    }    public void setUserId(Integer userId) {        this.userId = userId;    }    public List<CartItem> getCartItems() {        return cartItems;    }    public void setCartItems(List<CartItem> cartItems) {        this.cartItems = cartItems;    }    @Override    public String toString() {        return "ReserveItemsRequest [userId=" + userId +", cartItems=" + cartItems +"]";    }}

In CartItem.java:

import java.math.BigDecimal;import javax.validation.constraints.NotNull;import javax.validation.constraints.Positive;public class CartItem {    @NotNull(message = "Product ID must not be null")    private Integer productId;    @NotNull(message = "Quantity must not be null")    @Positive(message = "Quantity must be positive")    private Integer quantity;    @NotNull(message = "Price per unit must not be null")    @Positive(message = "Price must be positive")    private BigDecimal pricePerUnit;    public Integer getProductId() {        return productId;    }    public void setProductId(Integer productId) {        this.productId = productId;    }    public Integer getQuantity() {        return quantity;    }    public void setQuantity(Integer quantity) {        this.quantity = quantity;    }    public BigDecimal getPricePerUnit() {        return pricePerUnit;    }    public void setPricePerUnit(BigDecimal pricePerUnit) {        this.pricePerUnit = pricePerUnit;    }    @Override    public String toString() {        return "CartItem [productId=" + productId +", quantity=" + quantity +", pricePerUnit=" + pricePerUnit +"]";    }}

It is certain that the validation is occurring but the MethodArgumentNotValidException is not thrown in console with all details about where the validation failed. And in Postman as well why do I get the repsonse in html format rather than JSON.


Viewing all articles
Browse latest Browse all 3744

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>