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

调用外部WebService后控制器返回500错误求助

问题分析与解决方案

核心问题

调用外部WebService时,短耗时场景下WS返回200控制器正常响应;但WS处理耗时数分钟(仍返回200)时,控制器却返回500错误,AJAX和表单提交均出现此问题。

可能原因

  1. JAX-RS Client未设置超时:默认连接/读取超时较短,WS长耗时触发客户端超时异常
  2. 服务器端请求超时:如Tomcat默认20秒连接超时,控制器处理超时时直接断开连接返回500
  3. 异常处理漏洞:SendNotification.send()中资源关闭时的异常可能覆盖原调用异常,导致控制器未正确捕获
  4. Session超时:HttpSession超时时间短于WS处理时长,引发会话失效异常

修复方案

1. 给JAX-RS Client添加超时配置

在创建Client时显式设置足够长的连接和读取超时,匹配WS最长处理时间:

client = ClientBuilder.newBuilder()
        .sslContext(Conexiones.configurarSSL())
        // 连接超时(示例:5分钟)
        .connectTimeout(5, TimeUnit.MINUTES)
        // 读取超时(示例:10分钟,按需调整)
        .readTimeout(10, TimeUnit.MINUTES)
        .build();

2. 修复异常处理逻辑

避免资源关闭时的异常覆盖原调用异常,同时确保异常能传递到控制器:

} catch (Exception ex) {
    logger.error("SendNotification.send", ex);
    throw ex; // 重新抛出异常,让上层控制器捕获处理
} finally {
    // 单独处理资源关闭的异常,避免覆盖原错误
    if (res != null) {
        try {
            res.close();
        } catch (Exception e) {
            logger.error("Failed to close Response", e);
        }
    }
    if (client != null) {
        try {
            client.close();
        } catch (Exception e) {
            logger.error("Failed to close Client", e);
        }
    }
}

3. 调整服务器端超时配置

Tomcat(传统部署)

修改server.xml的Connector配置,延长超时时间:

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="600000" <!-- 10分钟 -->
           redirectPort="8443"/>

Spring Boot

在application.properties中添加:

# Tomcat连接超时
server.tomcat.connection-timeout=600000
# Spring MVC异步请求超时
spring.mvc.async.request-timeout=600000

4. 改用异步处理(推荐)

同步长耗时请求易触发超时,改用异步模式避免阻塞容器线程:

@PostMapping(value = "/xyz.htm", params="callWebService")
@ResponseBody
public DeferredResult<String> callWebService(final HttpSession session, HttpServletRequest request) {   
    DeferredResult<String> deferredResult = new DeferredResult<>(600000L); // 设置异步超时
    String errorResult = "{\"messageType\":\"error\",\"message\":\"Updated error\"}";
    
    CompletableFuture.runAsync(() -> {
        try {
            if (SendNotification.send()) {
                deferredResult.setResult("{\"messageType\":\"info\",\"message\":\"Updated\"}");
            } else {
                deferredResult.setResult(errorResult);
            }
        } catch (Exception e) {
            logger.error("xyz.callWebService -- Error calling WS", e);
            deferredResult.setResult(errorResult);
        }
    });
    
    return deferredResult;
}

同时在Spring配置类上添加@EnableAsync注解开启异步支持。

额外检查

  • 查看服务器日志(如Tomcat的catalina.out),定位500错误的具体堆栈,确认超时类型
  • 检查HttpSession超时时间,若会话在WS处理中失效,需延长超时或避免异步逻辑依赖session

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 01:05:01