xkcoding/spring-boot-demo · info · SecurityException

400

400

Error message

参数不能为空!

What it means

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.

Source

Thrown at demo-rbac-security/src/main/java/com/xkcoding/rbac/security/controller/MonitorController.java:54

     *
     * @param pageCondition 分页参数
     */
    @GetMapping("/online/user")
    public ApiResponse onlineUser(PageCondition pageCondition) {
        PageUtil.checkPageCondition(pageCondition, PageCondition.class);
        PageResult<OnlineUser> pageResult = monitorService.onlineUser(pageCondition);
        return ApiResponse.ofSuccess(pageResult);
    }

    /**
     * 批量踢出在线用户
     *
     * @param names 用户名列表
     */
    @DeleteMapping("/online/user/kickout")
    public ApiResponse kickoutOnlineUser(@RequestBody List<String> names) {
        if (CollUtil.isEmpty(names)) {
            throw new SecurityException(Status.PARAM_NOT_NULL);
        }
        if (names.contains(SecurityUtil.getCurrentUsername())) {
            throw new SecurityException(Status.KICKOUT_SELF);
        }
        monitorService.kickout(names);
        return ApiResponse.ofSuccess();
    }
}

View on GitHub (pinned to 87a142f960)

Solutions

  1. Ensure the client sends at least one username in the request body array.
  2. 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.
  3. Verify the frontend selection logic populates the array before enabling the kickout button.
Defensive patterns

Strategy: validation

Validate before calling

// Validate the names list is non-empty before calling kickout
if (names == null || names.isEmpty()) {
    return ResponseEntity.badRequest().body("用户名列表不能为空");
}

Try / catch

// In a @ControllerAdvice handler for SecurityException
@ExceptionHandler(SecurityException.class)
@ResponseBody
public ResponseEntity<ApiResponse> handleSecurityException(SecurityException e) {
    Status status = e.getStatus();
    if (status.getCode() == 400) {
        return ResponseEntity.badRequest().body(ApiResponse.ofStatus(status));
    }
    return ResponseEntity.status(500).body(ApiResponse.ofStatus(Status.ERROR));
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of xkcoding/spring-boot-demo@87a142f960 (2026-08-14). Data as JSON: /api/errors/2d174d6366b7f265. Report an issue: GitHub.