Spring Boot's validation framwork provides server-side data validation capabilities, though this approach increases server load due to the extensive code executino path required for HTTP requests. This makes Spring particularly suitable for systems with moderate real-time requirements and sufficient resoucres.
Custom Validator Implementation
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class PositiveMessageValidator implements ConstraintValidator<PositiveMessageCheck, String> {
@Override
public boolean isValid(String inputValue, ConstraintValidatorContext validatorContext) {
if(inputValue == null || inputValue.trim().isEmpty()) {
return true;
}
String processedMessage = inputValue.trim();
return !processedMessage.contains("negative phrase") && !processedMessage.contains("unmotivated");
}
}
Custom Annotation Definition
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PositiveMessageValidator.class)
@Documented
public @interface PositiveMessageCheck {
String message() default "Message must be positive";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Data Model with Validation Constraints
import javax.validation.constraints.NotNull;
import javax.validation.constraints.DecimalMax;
import java.math.BigDecimal;
import java.util.Date;
public class ProductSale {
private Integer productId;
@NotNull(message = "Product name is required")
private String productName;
@DecimalMax(message = "Quantity cannot exceed 10000", value = "10000")
private BigDecimal quantity;
private BigDecimal unitPrice;
private BigDecimal totalValue;
@PositiveMessageCheck(message = "Please provide motivational comments")
private String remarks;
private Date transactionDate;
// Getter and setter methods
public Integer getProductId() { return productId; }
public void setProductId(Integer productId) { this.productId = productId; }
public String getProductName() { return productName; }
public void setProductName(String productName) { this.productName = productName; }
public BigDecimal getQuantity() { return quantity; }
public void setQuantity(BigDecimal quantity) { this.quantity = quantity; }
public BigDecimal getUnitPrice() { return unitPrice; }
public void setUnitPrice(BigDecimal unitPrice) { this.unitPrice = unitPrice; }
public BigDecimal getTotalValue() { return totalValue; }
public void setTotalValue(BigDecimal totalValue) { this.totalValue = totalValue; }
public String getRemarks() { return remarks; }
public void setRemarks(String remarks) { this.remarks = remarks; }
public Date getTransactionDate() { return transactionDate; }
public void setTransactionDate(Date transactionDate) { this.transactionDate = transactionDate; }
}
Controller Implementation
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@Controller
@RequestMapping("/api/sales")
public class SalesController {
@Autowired
private SalesProcessingService salesService;
@PostMapping("/record")
@ResponseBody
public Object createSalesRecord(@RequestBody @Valid ProductSale saleData, Errors validationErrors) {
if (validationErrors.hasErrors()) {
return ValidationUtil.extractErrorMessages(validationErrors);
}
try {
if (saleData.getTotalValue() == null) {
saleData.setTotalValue(saleData.getQuantity().multiply(saleData.getUnitPrice()));
}
return salesService.processSale(saleData);
} catch (DataValidationException ex) {
return ApiResponse.error(ex.getMessage());
}
}
}
Client-Side Test Code
const requestConfig = {
url: 'http://localhost:9999/api/sales/record',
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
data: JSON.stringify({
productName: "Rice",
quantity: 10000.1,
unitPrice: 1000,
remarks: "negative phrase"
})
};
$.ajax(requestConfig).done(function(response) {
console.log(response);
});
Validation Response
{
"remarks": "Please provide motivational comments",
"quantity": "Quantity cannot exceed 10000"
}