Java调用API异常需分层应对:网络层设超时与DNS预检,协议层校验URL编码与Content-Type,解析层防空指针与类型不匹配,业务层按code分类透出语义。

Java调用API接口抛异常,不是“能不能避免”,而是“怎么分层应对”。核心思路是:网络问题早拦截、协议错误快识别、解析失败有兜底、业务异常可感知。
网络连接异常要提前设防
这类异常发生在请求发出前或刚建立连接时,比如 ConnectException、UnknownHostException、ConnectTimeoutException。它们往往意味着服务不可达,而不是业务出错。
- 设置合理的连接超时(如 3–5 秒)和读取超时(如 10–30 秒),避免线程卡死
- 调用前可用
InetAddress.getByName("api.example.com")预检 DNS 是否通 - 生产环境禁用 SSL 证书忽略逻辑;测试环境若需绕过,必须显式注释并加开关控制
- 代理配置(
http.proxyHost等)需统一管理,避免硬编码导致环境间差异
HTTP 协议层异常需严格校验
这类异常反映请求本身不合规,比如 ProtocolException、SSLHandshakeException、MalformedURLException。多数源于开发疏漏,而非服务端问题。
- URL 中的参数必须用
URLEncoder.encode()编码,尤其含中文、空格、斜杠等字符 - POST/PUT 请求务必设置
Content-Type: application/json,否则很多服务直接拒收 - HTTPS 调用失败时,先用
openssl s_client -connect api.example.com:443检查证书链是否完整 - 避免手动拼接 URL 或 Header,优先使用 HttpClient 或 OkHttp 的 Builder 模式构造请求
响应解析异常必须类型对齐
服务器返回了数据,但 Java 解析失败——这是最隐蔽也最常被忽视的一类,典型如 JsonParseException、JsonMappingException、NullPointerException。
立即学习“Java免费学习笔记(深入)”;
- 不要假设响应体一定是 JSON;先检查
response.body()内容,警惕 HTML 错误页(如 502/503 返回的 Nginx 页面) - POJO 字段类型要和服务端实际返回严格一致;字符串数字字段建议用
String接收再转,或配@JsonDeserialize(using = StringToIntDeserializer.class) - 所有可能为 null 的字段,在 getter 或业务逻辑中做判空,或用 Lombok
@NonNull+ 构造器校验 - 日期字段统一用
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")显式声明格式,避免时区/格式错乱
业务异常要分类透出语义
HTTP 状态码是表层信号,真正关键的是业务返回体里的 code 和 message。不能只看 200 就认为成功。
- 约定清晰的错误码体系:例如
0成功,400xx用户操作类(如参数错、权限不足),500xx系统级(如下游超时、DB 异常) - 对非 0 code,统一包装成自定义异常(如
BusinessException或RemoteServiceException),带原始 code/message/traceId -
前端或 App 不应直接解析 HTTP 状态码做提示;应以响应体中的
returnCode为准,200+非0 code 属于“业务失败”,不是“调用失败” - 系统异常(如 500xx)建议自动记录告警日志,并触发轻量重试(最多 2 次,指数退避);用户操作异常(如 400xx)直接透传 message 给前端
基本上就这些。异常不是 bug 的替罪羊,而是接口契约的照妖镜。每次抛异常,都该反问一句:这个错误,是网络没通?请求写错了?JSON 格式对不上?还是业务规则被违反了?分清层级,处理就不难。










