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

Jersey发送带请求体GET请求报Entity must be null异常如何解决

问题描述

调用支付服务商外部API时,选用Jersey与javax.ws.rs发起请求,利用框架内置能力实现Digest认证。但发起携带payload载荷的GET请求时,框架返回如下异常:

IllegalStateException. Entity must be null for http method GET

对应业务实现代码如下:

CashTransactionResponse responseData = null;
// 对接intouch服务端
String requestUrl = rootUrlTouchPay + agency.getAgencyCode() + "/" + IntouchMethodApis.TRANSACTION + "?loginAgent=" + agency.getLogin() + "&passwordAgent=" + agency.getPassword();

ClientConfig clientConfig = new ClientConfig();
// 开启Digest认证
HttpAuthenticationFeature feature = HttpAuthenticationFeature.digest(BASIC_LOGIN, BASIC_PWD);
clientConfig.register(feature);

clientConfig.register(JacksonFeature.class);
// 创建REST客户端
Client client = ClientBuilder.newClient(clientConfig);
clientConfig.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
// 构造请求地址
WebTarget webTarget = client.target(requestUrl);
Invocation.Builder invocationBuilder = webTarget.request(javax.ws.rs.core.MediaType.APPLICATION_JSON);

logger.info("Initialisation of cashout service successful for cash");

// 序列化请求参数
Gson gson = new Gson();
String transactionString = gson.toJson(cashRequest);

Response response = null;
// 发起请求
if (cashRequest.getServiceCode().contains(TelecomEnum.WAVE.name().toUpperCase())) {
    response = invocationBuilder.method("GET", Entity.entity(transactionString, javax.ws.rs.core.MediaType.APPLICATION_JSON));
} else {
    response = invocationBuilder.put(Entity.entity(transactionString, javax.ws.rs.core.MediaType.APPLICATION_JSON));
}

需要实现携带请求体的GET请求发送能力。

解决方案

根因说明

HTTP/1.1规范中GET方法的语义为资源检索,未对GET请求携带请求体的行为做统一标准化约定,Jersey作为合规HTTP客户端实现,默认会拦截携带实体的GET请求,直接抛出上述异常。
另外现有代码存在配置顺序错误:SUPPRESS_HTTP_COMPLIANCE_VALIDATION(关闭HTTP合规校验)属性的设置在ClientBuilder.newClient()调用之后,Client实例创建时已经完成配置加载,该校验关闭参数实际未生效。

修复操作

  • 调整配置加载顺序,将合规校验关闭的配置移到Client实例创建之前:
ClientConfig clientConfig = new ClientConfig();
// 注册Digest认证、JSON序列化组件
HttpAuthenticationFeature feature = HttpAuthenticationFeature.digest(BASIC_LOGIN, BASIC_PWD);
clientConfig.register(feature);
clientConfig.register(JacksonFeature.class);
// 提前关闭HTTP规范校验,再实例化Client
clientConfig.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
Client client = ClientBuilder.newClient(clientConfig);
  • 如果调整顺序后依然抛出相同异常,说明当前使用的Jersey版本在请求构造逻辑中硬编码了GET方法禁止携带实体的判断,可替换为Apache HttpClient连接器绕过原生校验:
    1. 引入和当前Jersey版本匹配的jersey-apache-connector依赖
    2. 给ClientConfig添加连接器配置:
    clientConfig.connectorProvider(new ApacheConnectorProvider());
    
  • 客户端侧绕过校验后,需要额外确认目标支付服务商的网关、负载均衡、WAF、服务端程序不会主动丢弃GET请求的请求体:大量HTTP中间件默认会忽略GET请求的body内容,很容易出现参数丢失的问题。如果联调时发现服务端收不到请求体参数,优先和服务商确认接口文档的请求方法是否标注错误,这类要求GET带请求体的场景,多数是文档笔误,实际要求使用POST/PUT方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:09:19