Spring WebServiceTemplate配置超时不生效问题如何解决
问题根因
你为WebServiceTemplate配置了两个消息发送器,运行时会按列表顺序优先匹配第一个BasicAuthHttpsConnectionMessageSender处理请求,你设置的5ms超时仅配置在第二个消息发送器上,因此不会生效。
未显式设置超时的HTTP消息发送器默认使用JDK HttpURLConnection的默认超时规则,超时值为0代表永不超时,你观测到的5秒耗时属于服务端或网络层面的默认超时限制。
解决方法
方案1:直接为自定义认证消息发送器配置超时
如果你的BasicAuthHttpsConnectionMessageSender继承自HttpWebServiceMessageSender,直接在构造时为其设置超时参数即可,无需额外添加第二个消息发送器:
@Bean public WebServiceTemplate webServiceTemplate(final WebServiceTemplateBuilder builder) { BasicAuthHttpsConnectionMessageSender authSender = new BasicAuthHttpsConnectionMessageSender(props.getUsername(), props.getPassword()); // 直接给认证用的消息发送器设置超时 authSender.setConnectTimeout(Duration.ofMillis(5)); authSender.setReadTimeout(Duration.ofMillis(5)); return builder.setMarshaller(marshaller()).setUnmarshaller(marshaller()) .messageSenders(List.of(authSender)) .build(); }
方案2:基于HttpComponents统一配置认证+超时
如果你的场景需要使用HttpComponentsMessageSender,可以在构造HttpClient时就将认证凭据和超时参数一并配置,再注入到WebServiceTemplate中:
@Bean public HttpComponentsMessageSender authMessageSender() { // 配置认证凭据 UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(props.getUsername(), props.getPassword()); CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, credentials); // 配置全局超时参数 RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(5) .setSocketTimeout(5) .build(); HttpClient httpClient = HttpClientBuilder.create() .setDefaultCredentialsProvider(credentialsProvider) .setDefaultRequestConfig(requestConfig) .build(); return new HttpComponentsMessageSender(httpClient); } @Bean public WebServiceTemplate webServiceTemplate(final WebServiceTemplateBuilder builder) { return builder.setMarshaller(marshaller()).setUnmarshaller(marshaller()) .messageSenders(List.of(authMessageSender())) .build(); }
注意事项
5ms的超时阈值非常低,仅适用于本地同机房服务调用场景,生产环境建议根据接口实际响应耗时调整到合理值,避免正常请求被误拦截。
内容的提问来源于stack exchange,提问作者SorryForAsking
相关产品推荐
相关产品推荐

