You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止GET API接收不必要请求体并返回400 Bad Request错误

问题描述

我有一个通过路径参数传递员工ID返回员工详情的GET API,示例URL为http://localhost:8080/employee/155(其中155是员工ID),API会返回对应ID的员工信息。控制器代码如下:

@GET
@Produces({MediaType.APPLICATION_JSON})
@Path("/{employee-id}")
public Response getEmployeeDetails(@PathParam("employee-id") int empId);

当前存在的问题:即使该API收到不必要的请求体,仍会正常返回员工详情。需要实现拦截此类请求,当发送不必要请求体时返回400 Bad Request错误。例如:

URI - http://localhost:8080/employee/155
Request - {"name":"hello","position":"tech"}
当前Response - 200 OK 和员工ID 155的详情
期望Response - 400 Bad Request

解决方案

方法1:全局拦截(推荐)

创建一个JAX-RS过滤器,拦截所有带请求体的GET请求,直接返回400错误:

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.io.IOException;

@Provider
public class GetRequestBodyBlocker implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        if ("GET".equalsIgnoreCase(requestContext.getMethod()) && requestContext.hasEntity()) {
            requestContext.abortWith(
                Response.status(Response.Status.BAD_REQUEST)
                        .entity("GET请求不允许携带请求体")
                        .build()
            );
        }
    }
}

把这个类放到项目的JAX-RS扫描路径下,就会自动生效,所有带请求体的GET请求都会被拦截。

方法2:针对单个API处理

如果只想限制这个员工详情接口,可以在方法里检查请求体是否存在:

@GET
@Produces({MediaType.APPLICATION_JSON})
@Path("/{employee-id}")
public Response getEmployeeDetails(@PathParam("employee-id") int empId, 
                                   @Context HttpServletRequest request) throws IOException {
    // 检查请求是否有内容
    if (request.getContentLength() > 0 || request.getInputStream().available() > 0) {
        return Response.status(Response.Status.BAD_REQUEST)
                .entity("GET请求不允许携带请求体")
                .build();
    }
    // 原有逻辑:查询员工详情并返回
    Employee emp = employeeDao.getById(empId);
    return Response.ok(emp).build();
}

注意:如果请求流已经被其他组件提前读取,available()可能无法准确判断,这种情况下优先用全局过滤器。

方法3:利用@Consumes注解限制

显式声明该GET接口不接受任何媒体类型,当有请求体时框架会自动返回400:

@GET
@Produces({MediaType.APPLICATION_JSON})
@Path("/{employee-id}")
@Consumes({}) // 空集合表示不接受任何媒体类型
public Response getEmployeeDetails(@PathParam("employee-id") int empId) {
    // 原有逻辑
}

这种方式简单,但不同JAX-RS实现(如Jersey、RestEasy)的兼容性可能有差异,建议测试后使用。

内容的提问来源于stack exchange,提问作者Vedha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 03:47:48