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
相关产品推荐
相关产品推荐

