Reputation: 251
I have a Spring Boot application (with version 2.4.5) as a Kotlin project. Now when I enter something invalid, I get an error message, but not my error message that I set in the annotation.
Controller
@PostMapping(value = ["/seatMap/save"])
fun addSeatPlan(@RequestPart @Valid data: DSeatMap, @RequestPart image: MultipartFile?, auth: AuthenticationToken) {
try {
if (data.uuid == null) {
seatService.addSeatMap(auth.organisation!!, data, image)
} else {
seatService.updateSeatMap(data, auth.organisation!!, image)
}
} catch (e: UnauthorizedException) {
throw e
}
}
Data class
import java.util.*
import javax.validation.constraints.NotEmpty
data class DSeatMap(
var uuid: UUID?,
@field:NotEmpty(message = "name is empty")
val name: String,
var data: String,
val quantity: Int,
var settings: DSettings?
)
My Response, here should be message = "name is empty"
{
"timestamp": "2021-04-22T19:47:08.194+00:00",
"status": 400,
"error": "Bad Request",
"message": "Validation failed for object='data'. Error count: 1",
}
If I set the property it shows me the correct one but I don't want to have all the side information I only want to output the message
server.error.include-binding-errors=always
Result:
{
"timestamp": "2021-04-22T19:56:30.058+00:00",
"status": 400,
"error": "Bad Request",
"message": "Validation failed for object='data'. Error count: 1",
"errors": [
{
"codes": [
"NotEmpty.data.name",
"NotEmpty.name",
"NotEmpty.java.lang.String",
"NotEmpty"
],
"arguments": [
{
"codes": [
"data.name",
"name"
],
"arguments": null,
"defaultMessage": "name",
"code": "name"
}
],
"defaultMessage": "name is empty",
"objectName": "data",
"field": "name",
"rejectedValue": "",
"bindingFailure": false,
"code": "NotEmpty"
}
],
"path": "/api/dashboard/seatMap/save"
}
Upvotes: 8
Views: 14408
Reputation: 1382
Please here you can find an optimised solution :
@ControllerAdvice
public class ControllerAdvisor extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
var errors = new HashMap<>();
for (var err : ex.getBindingResult().getAllErrors())
errors.put(((FieldError) err).getField(), err.getDefaultMessage());
return this.handleExceptionInternal(ex, errors, headers, status, request);
}
}
Upvotes: 0
Reputation: 11
Please create the following ControllerAdvice
with the corresponding ExceptionHandler
. Should be something like this:
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, String> handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error) -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
return errors;
}
}
In the recent Spring Boot versions, the sending of error messages was disabled, and now needs to be manually implemented like shown above.
Reference: https://www.baeldung.com/spring-boot-bean-validation#the-exceptionhandler-annotation
Upvotes: 1
Reputation: 251
Ok finally I found a solution. I created a global exception handler that listens to the MethodArgumentNotValidException. After that I manipulate the message and set the validation message that I set before in the annotation
@RestControllerAdvice
class ExceptionControllerAdvice {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException::class)
fun handleValidationExceptions(ex: MethodArgumentNotValidException): Map<String, String?>? {
val errors: MutableMap<String, String?> = HashMap()
ex.bindingResult.allErrors.forEach { error: ObjectError ->
val fieldName = (error as FieldError).field
val errorMessage = error.getDefaultMessage()
errors[fieldName] = errorMessage
}
return errors
}
}
Source: https://www.baeldung.com/spring-boot-bean-validation
Upvotes: 6
Reputation: 452
@Yunz I think the "errors" attribute gets added to your response since you set
server.error.include-binding-errors=always
can you try setting that to never
or don't define this property and rely on default(which is never
).
you need to set the server.error.include-message=always
since version 2.3, Spring Boot hides the message field in the response to avoid leaking sensitive information; we can use this property with an always value to enable it
for details check out the spring boot documentation:
Upvotes: 6