如何编写等效HttpClient4.5异常POST请求的curl命令复现500错误
问题根因
核心错误是对HttpClient的StringEntity.setContentEncoding()方法存在用法误解:
- 该方法设置的是HTTP协议中的
Content-Encoding请求头,而非Content-Type头。Content-Encoding的标准取值仅用来标识请求体的压缩/传输编码格式,合法值仅为gzip、deflate、br这类编码标识。 - 你的代码将
application/json; charset=UTF-8这个属于Content-Type的值传入了setContentEncoding()方法,最终会给请求额外追加一个完全不符合规范的Content-Encoding: application/json; charset=UTF-8请求头。 - 服务端收到该非法头后,会按照头里声明的编码格式解析请求体,解析逻辑直接触发内部异常,因此返回500响应。当你移除这段错误代码后,非法的Content-Encoding头不会随请求发出,仅保留你通过
post.setHeader()设置的合法Content-Type头,接口就可以正常返回200响应。 - 你之前编写的curl命令仅携带了正确的Content-Type头,没有带上这个非法的Content-Encoding头,因此始终无法复现500错误。
复现500错误的等效curl命令
只需要在原有curl命令中追加对应的非法Content-Encoding头即可,和原异常代码完全等效的命令如下:
curl -vwX POST "替换为你的实际请求URL" \ -H "Content-Type: application/json; charset=UTF-8" \ -H "Content-Encoding: application/json; charset=UTF-8" \ -d '替换为你的实际JSON请求体'
注意:为了和Java代码行为完全对齐,Content-Type头的值要和代码中
post.setHeader()设置的完全一致,带上charset=UTF-8后缀,不要遗漏。
代码修复参考
原代码中完全不需要调用entity.setContentEncoding()方法,如果要给请求实体设置Content-Type,直接在构造StringEntity时指定即可,从根源避免写错请求头:
// 构造请求实体时直接指定标准JSON内容类型,内部会自动处理Content-Type头 StringEntity entity = new StringEntity(jsonRequest, ContentType.APPLICATION_JSON); post.setEntity(entity);
这种写法不会生成多余的非法请求头,逻辑更简洁也不会出现这类低级错误。
内容的提问来源于stack exchange,提问作者Srikar Rao
相关产品推荐
相关产品推荐

