Spring MVC如何强制接口请求体必须为空
可以实现强制要求该接口请求体为空
当前接口会自动忽略所有传入的请求体,原因是方法没有声明任何带@RequestBody注解的入参,Spring MVC默认不会解析、绑定请求体内容,客户端传什么都不会被处理,也不会触发校验。
单接口快速实现
直接给方法加一个可选的请求体入参,手动判断非空返回400即可,改动最小:
@DeleteMapping ResponseEntity<?> delete( @RequestAttribute(USER_KEY) User user, @RequestBody(required = false) String rawBody ) { if (rawBody != null && !rawBody.isBlank()) { return ResponseEntity.badRequest().build(); } service.delete(user.getId()); return ResponseEntity.ok().build(); }
这种方式不需要额外写任何组件,只改对应接口代码就行,适合只有少量接口需要做这个限制的场景。
多接口统一管控
如果项目里有多个接口都要求请求体为空,没必要每个接口都写重复判断,可以自定义注解+拦截器实现全局统一校验:
- 先定义标记注解:
import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface EmptyBodyRequired { }
- 写拦截器做统一校验:
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import java.util.stream.Collectors; @Component public class EmptyBodyCheckInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod method) { if (method.hasMethodAnnotation(EmptyBodyRequired.class)) { // 注意:正式使用建议提前用ContentCachingRequestWrapper包装请求,避免请求体流读完后后续逻辑无法读取 String body = request.getReader().lines().collect(Collectors.joining()); if (!body.isBlank()) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "该接口不允许携带请求体"); return false; } } } return true; } }
- 把拦截器注册到Spring MVC的拦截器链里,之后只要在需要限制请求体为空的接口方法上加上
@EmptyBodyRequired注解就会自动生效。
注意事项
- 用拦截器方案的时候,一定要先把请求对象用
ContentCachingRequestWrapper包装一层,不然请求体的输入流被拦截器读完之后,后续控制器/过滤器如果要读请求体就会拿到空内容,引发业务异常。 - 如果只是单接口做限制,优先用第一种直接加入参判断的方案,Spring会自动处理请求体流的复用问题,不会有坑。
内容的提问来源于stack exchange,提问作者ashur
相关产品推荐
相关产品推荐

