How to validate Spring Boot Rest response?
10,260
Solution 1
Implemented response validator:
@Aspect
@Component
public class ControllerResponseValidator {
Logger logger = Logger.getLogger(ControllerResponseValidator.class);
@Autowired
private Validator validator;
@AfterReturning(pointcut = "execution(* com.example.controller.*.*(..))", returning = "result")
public void validateResponse(JoinPoint joinPoint, Object result) {
validateResponse(result);
}
private void validateResponse(Object object) {
Set<ConstraintViolation<Object>> validationResults = validator.validate(object);
if (validationResults.size() > 0) {
StringBuffer sb = new StringBuffer();
for (ConstraintViolation<Object> error : validationResults) {
sb.append(error.getPropertyPath()).append(" - ").append(error.getMessage()).append("\n");
}
String msg = sb.toString();
logger.error(msg);
throw new RestException(HttpStatus.INTERNAL_SERVER_ERROR, msg);
}
}
}
Solution 2
Use @Validated
on Rest Controller and @Valid
on the method for which the return object has to be validated. For Example:
RestController:
@RestController
@RequestMapping("/tasks")
@Validated
public class TaskController {
@GetMapping("/{taskId}")
@Valid
public TaskDTO getTask(@PathVariable UUID taskId) {
return convertToDto(taskService.findById(taskId));
}
}
DTO class:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ValidTaskDTO
public class TaskDTO {
@FutureOrPresent
@NotNull
private ZonedDateTime dueDate;
@NotBlank(message = "Title cannot be null or blank")
private String title;
private String description;
@NotNull
private RecurrenceType recurrenceType;
@Future
@NotNull
private ZonedDateTime repeatUntil;
}
My return object TaskDTO
has null dueDate
and repeatUntil
. So the error message will be as shown below:
{
"timestamp": "2021-01-20T11:09:37.303929",
"status": 400,
"error": "Bad Request",
"message": "getTask.<return value>.dueDate: must not be null, getTask.<return value>.repeatUntil: must not be null",
"path": null
}
I hope this helps. For details on custom class level constraint, have a look at this video.
Author by
Justinas Jakavonis
Updated on June 20, 2022Comments
-
Justinas Jakavonis almost 2 years
I have controller implemented with Spring Boot Rest:
@RestController @RequestMapping("/example") public class ExampleController { @Autowired private ExampleService exampleService; @GetMapping("/{id}") public ExampleResponse getExample(@NotNull @PathVariable("id") String id) { return exampleService.getExample(id); } }
And response DTO:
public class ExampleResponse { @NotNull private String id; @NotNull private String otherStuff; // setters and getters }
Response body is not validated. I have annotated it with
@Valid
butnull
values still pass. Request validation works well.How to validate response body?
-
ch271828n about 3 yearswonderful - works for me! (I wonder why nobody upvoted this excellent answer!)