如何从WebClientResponseException中获取响应体?
解决WebClient获取400响应体乱码问题
问题根源
你遇到的乱码是因为响应体被Gzip压缩了,从你提供的字节数组开头[31, -117]可以判断——这是Gzip压缩数据的标准魔数(对应十六进制0x1F8B)。Insomnia等客户端会自动识别并解压Gzip响应,但WebClient默认在抛出WebClientResponseException时,没有自动解压异常响应体,导致直接读取得到的是压缩后的二进制数据,表现为乱码。
解决方案
方案1:配置WebClient自动处理Gzip压缩
修改WebClient的构建配置,添加Gzip编解码器,让它自动处理请求的压缩协商和响应的解压(包括异常场景):
import org.springframework.http.codec.GzipDecoder; import org.springframework.http.codec.GzipEncoder; import org.springframework.web.reactive.function.client.WebClient; WebClient webClient = WebClient.builder() .codecs(configurer -> { // 启用Gzip解码,自动解压响应 configurer.defaultCodecs().gzipDecoder(new GzipDecoder()); // 可选:启用Gzip编码,请求时发送Accept-Encoding: gzip头 configurer.defaultCodecs().encoder(new GzipEncoder()); }) .build();
配置完成后,WebClient会自动处理Gzip压缩的响应,无论请求成功还是抛出异常,调用getResponseBodyAsString()或getResponseBodyAs(Class)都能得到正常的内容。
方案2:手动解压异常响应体
如果无法修改WebClient的全局配置,可以在捕获异常时,手动对字节数组进行Gzip解压:
import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.zip.GZIPInputStream; import org.springframework.web.reactive.function.client.WebClientResponseException; try { // 你的WebClient请求代码 } catch (WebClientResponseException.BadRequest e) { try (GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(e.getResponseBodyAsByteArray()))) { // 解压后转为UTF-8字符串 String decodedBody = new String(gzipInputStream.readAllBytes(), StandardCharsets.UTF_8); // 后续可以将字符串转为JSON对象或POJO System.out.println(decodedBody); } catch (IOException ex) { // 处理解压失败的异常 ex.printStackTrace(); } }
验证步骤
可以先打印响应头确认压缩类型,验证问题根源:
System.out.println("Content-Encoding: " + e.getHeaders().getFirst("Content-Encoding"));
输出应该为gzip,说明响应确实是Gzip压缩的。
内容的提问来源于stack exchange,提问作者László Temesi
相关产品推荐
相关产品推荐

