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

Jersey客户端异常处理:如何通过ClientResponseFilter获取响应内容?

解决Jersey ClientResponseFilter无法获取响应内容的问题

这个问题我之前也碰到过!核心原因是Jersey里的ClientResponseContext的实体流只能被读取一次,而且默认情况下,当过滤器触发时,这个流可能已经被Jersey内部处理过了,导致你直接读取拿不到内容。下面给你一个可行的解决方案:

步骤1:定义自定义异常类

先和服务端返回的异常格式对应,定义一个自定义异常类,比如:

public class CustomServerException extends RuntimeException {
    private int errorCode;
    private String errorMessage;

    public CustomServerException(int errorCode, String errorMessage) {
        super(errorMessage);
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
    }

    // 省略getter/setter方法
}

步骤2:修改ExceptionFilter缓存响应流

关键是先把响应流缓存到内存中,既可以读取内容,又能重置流保证后续处理正常进行,代码如下:

import com.fasterxml.jackson.databind.ObjectMapper;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

@Provider
public class ExceptionFilter implements ClientResponseFilter {
    // 用Jackson解析服务端返回的JSON异常信息
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
        int status = responseContext.getStatus();
        if (status != Response.Status.OK.getStatusCode()) {
            // 1. 读取原始响应流并缓存到字节数组
            InputStream originalStream = responseContext.getEntityStream();
            ByteArrayOutputStream cachedStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = originalStream.read(buffer)) != -1) {
                cachedStream.write(buffer, 0, bytesRead);
            }
            byte[] responseBytes = cachedStream.toByteArray();

            // 2. 重置响应流,确保后续流程(如果有)能正常读取
            responseContext.setEntityStream(new ByteArrayInputStream(responseBytes));

            // 3. 解析响应内容为自定义异常
            String responseBody = new String(responseBytes);
            // 这里假设服务端返回的JSON格式是{"errorCode":xxx, "errorMessage":"xxx"}
            CustomServerException serverException = objectMapper.readValue(responseBody, CustomServerException.class);

            // 4. 抛出自定义异常,上层JavaFX代码可以捕获并处理
            throw serverException;
        }
    }
}

补充说明

  • 确保项目引入了Jackson依赖(比如jackson-databind),用来解析服务端返回的JSON异常信息;如果服务端返回的是其他格式,调整解析逻辑即可。
  • 过滤器上的@Provider注解不能少,这样Jersey才能识别并加载这个过滤器。
  • 上层调用Jersey客户端的代码可以直接捕获CustomServerException,然后在JavaFX界面上展示错误提示(比如弹出对话框)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:45:24