{"record":{"id":"2d174d6366b7f265","repo":"xkcoding/spring-boot-demo","slug":"400","errorCode":"400","errorMessage":"参数不能为空！","messagePattern":"参数不能为空！","errorType":"validation","errorClass":"SecurityException","httpStatus":null,"severity":"info","filePath":"demo-rbac-security/src/main/java/com/xkcoding/rbac/security/controller/MonitorController.java","lineNumber":54,"sourceCode":"     *\n     * @param pageCondition 分页参数\n     */\n    @GetMapping(\"/online/user\")\n    public ApiResponse onlineUser(PageCondition pageCondition) {\n        PageUtil.checkPageCondition(pageCondition, PageCondition.class);\n        PageResult<OnlineUser> pageResult = monitorService.onlineUser(pageCondition);\n        return ApiResponse.ofSuccess(pageResult);\n    }\n\n    /**\n     * 批量踢出在线用户\n     *\n     * @param names 用户名列表\n     */\n    @DeleteMapping(\"/online/user/kickout\")\n    public ApiResponse kickoutOnlineUser(@RequestBody List<String> names) {\n        if (CollUtil.isEmpty(names)) {\n            throw new SecurityException(Status.PARAM_NOT_NULL);\n        }\n        if (names.contains(SecurityUtil.getCurrentUsername())) {\n            throw new SecurityException(Status.KICKOUT_SELF);\n        }\n        monitorService.kickout(names);\n        return ApiResponse.ofSuccess();\n    }\n}\n","sourceCodeStart":36,"sourceCodeEnd":63,"githubUrl":"https://github.com/xkcoding/spring-boot-demo/blob/87a142f9604c1a5365b4d24d22c2c11c26a9d5ab/demo-rbac-security/src/main/java/com/xkcoding/rbac/security/controller/MonitorController.java#L36-L63","documentation":"Thrown by the kickout endpoint when the @RequestBody List<String> names is null or empty. CollUtil.isEmpty(names) returns true for both null and empty lists. The SecurityException wraps Status.PARAM_NOT_NULL (400). This is input validation at the controller boundary — the endpoint refuses to proceed without at least one username to kick.","triggerScenarios":"Sending DELETE /api/monitor/online/user/kickout with an empty JSON array ([]) or no body. CollUtil.isEmpty returns true and the exception fires before any kickout logic runs.","commonSituations":"Frontend bug sending an empty selection; client sending a request with no body at all (names deserializes to null); integration test with an empty payload; UI 'select all' logic producing an empty list when no users are online.","solutions":["Ensure the client sends at least one username in the request body array.","Add @NotEmpty validation on the request DTO (use a wrapper class with @NotEmpty List<String> names and @Valid) to get a 400 before reaching the controller body.","Verify the frontend selection logic populates the array before enabling the kickout button."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate the names list is non-empty before calling kickout\nif (names == null || names.isEmpty()) {\n    return ResponseEntity.badRequest().body(\"用户名列表不能为空\");\n}","typeGuard":null,"tryCatchPattern":"// In a @ControllerAdvice handler for SecurityException\n@ExceptionHandler(SecurityException.class)\n@ResponseBody\npublic ResponseEntity<ApiResponse> handleSecurityException(SecurityException e) {\n    Status status = e.getStatus();\n    if (status.getCode() == 400) {\n        return ResponseEntity.badRequest().body(ApiResponse.ofStatus(status));\n    }\n    return ResponseEntity.status(500).body(ApiResponse.ofStatus(Status.ERROR));\n}","preventionTips":["Validate the request body is a non-empty array on the client before sending.","Disable the kickout button when no users are selected in the UI.","Consider using a wrapper DTO with @NotEmpty validation for cleaner 400 responses."],"tags":["spring-security","validation","http-400","rbac","input-validation","monitor"],"backgroundTag":null,"analyzedSha":"87a142f9604c1a5365b4d24d22c2c11c26a9d5ab","analyzedAt":"2026-08-14T01:16:58.217Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}