[英]How to validate Spring Boot Rest response?
我用 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);
}
}
並回應 DTO:
public class ExampleResponse {
@NotNull
private String id;
@NotNull
private String otherStuff;
// setters and getters
}
響應正文未經驗證。 我已經用@Valid
注釋了它,但null
值仍然通過。 請求驗證效果很好。
如何驗證響應體?
已實現的響應驗證器:
@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);
}
}
}
在 Rest Controller 上使用@Validated
在必須驗證返回對象的方法上使用@Valid
。 例如:
休息控制器:
@RestController
@RequestMapping("/tasks")
@Validated
public class TaskController {
@GetMapping("/{taskId}")
@Valid
public TaskDTO getTask(@PathVariable UUID taskId) {
return convertToDto(taskService.findById(taskId));
}
}
DTO類:
@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;
}
我的返回對象TaskDTO
有 null dueDate
和repeatUntil
。 所以錯誤信息將如下所示:
{
"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
}
我希望這有幫助。 有關自定義類級別約束的詳細信息,請觀看此視頻。
您不應該將其注釋為以下代碼段嗎?
public @ResponseBody ExampleResponse getExample(@NotNull @PathVariable("id") String id) {
return exampleService.getExample(id);
}
您可以添加“@Validated @ResponseBody”注釋
public @Validated @ResponseBody getExample(@NotNull @PathVariable("id") String id) {
你期望發生什么? 我認為您應該考慮幾件事。
如果對象確實不能具有值為null
字段,則應在將對象保存到您的存儲庫(無論您喜歡哪種類型)時驗證這一點。 然后如果你的服務返回了一些東西,你就知道它已經有效了,如果它什么都不返回; 您可以為客戶端返回正確的狀態代碼和消息(4xx/5xx)。 您還可以將特定異常映射到某種類型的status code
這樣您就可以從代碼中拋出異常,並讓它們由 spring-boot 中的默認異常處理程序捕獲和處理
如果您的字段可以為null
,但您想在序列化中省略它們,則可以使用jackson annotations
。 @JsonInclude(JsonInclude.Include.NON_NULL)
只會序列化響應中的非空值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.