调用外部WebService后控制器返回500错误求助
问题分析与解决方案
核心问题
调用外部WebService时,短耗时场景下WS返回200控制器正常响应;但WS处理耗时数分钟(仍返回200)时,控制器却返回500错误,AJAX和表单提交均出现此问题。
可能原因
- JAX-RS Client未设置超时:默认连接/读取超时较短,WS长耗时触发客户端超时异常
- 服务器端请求超时:如Tomcat默认20秒连接超时,控制器处理超时时直接断开连接返回500
- 异常处理漏洞:
SendNotification.send()中资源关闭时的异常可能覆盖原调用异常,导致控制器未正确捕获 - 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
相关产品推荐
相关产品推荐

