Linux下JAX-WS SOAP服务运行一段时间后报401未授权异常
SOAP应用Linux环境运行一段时间后抛出401未授权异常
问题概述
开发的SOAP应用用于向目标服务发送请求,在Windows系统中可正常运行,但在Rocky Linux系统中运行5-10分钟后会停止工作,抛出401未授权异常。
异常堆栈信息
Servlet.service() for servlet [dispatcherServlet] in context with path [/api] threw exception [Request processing failed: org.springframework.ws.client.WebServiceTransportException: Unauthorized [401]] with root cause org.springframework.ws.client.WebServiceTransportException: Unauthorized [401] at org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:665) ~[spring-ws-core-4.0.2.jar!/:na] at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:587) ~[spring-ws-core-4.0.2.jar!/:na] at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:538) ~[spring-ws-core-4.0.2.jar!/:na] at
相关代码配置
客户端配置类
@Configuration @RequiredArgsConstructor public class CustomerPaymentClientConfig { @Bean public Jaxb2Marshaller marshaller() { Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); marshaller.setContextPath("com.example.wsdl"); return marshaller; } @Bean public WebServiceTemplate webServiceTemplate(WebServiceTemplateBuilder builder, Jaxb2Marshaller marshaller) throws Exception { return builder .setDefaultUri("https://service.example.com/WebPortalVC/PaymentWS") .setMarshaller(marshaller) .setUnmarshaller(marshaller) .build(); } }
SOAP客户端服务类
@Service @RequiredArgsConstructor public class GPPPaymentClient extends WebServiceGatewaySupport { private final WebServiceTemplate webServiceTemplate; private final Jaxb2Marshaller marshaller; public InitiatePaymentResponse InitiatePayment(MessageHeader messageHeader, InitiatePayment InitiationRequest) { JAXBElement<InitiatePaymentResponse> object = (JAXBElement<InitiatePaymentResponse>) webServiceTemplate.marshalSendAndReceive(InitiationRequest, webServiceMessage -> { try { String namespaceSer = "http://services.ws.payment.example.net/"; SoapMessage soapMessage = (SoapMessage) webServiceMessage; SoapHeader header = soapMessage.getSoapHeader(); header.addNamespaceDeclaration("ser", namespaceSer); ObjectFactory objectFactory = new ObjectFactory(); MessageHeader soapHeader = objectFactory.createMessageHeader(); soapHeader.setUserID(messageHeader.getUserID()); soapHeader.setReceiverID(messageHeader.getReceiverID()); soapHeader.setTransactionID(messageHeader.getTransactionID()); soapHeader.setMessageDateTime(messageHeader.getMessageDateTime()); JAXBElement<MessageHeader> headerElement = new JAXBElement<>(new QName("http://services.ws.payment.example.net/", "messageHeader"), MessageHeader.class, null, soapHeader); marshaller.marshal(headerElement, header.getResult()); JAXBElement<InitiatePayment> bodyElement = new JAXBElement<>(new QName("http://test.ws.payment.example.net/", "InitiatePayment"), InitiatePayment.class, null, InitiationRequest); marshaller.marshal(bodyElement, soapMessage.getPayloadResult()); } catch (Exception e) { log.info(e.toString()); } }); return object.getValue(); } }
SSL证书信任配置
@Bean public void addProperties() { System.setProperty("javax.net.ssl.keyStore", keyStoreLocation); System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword); System.setProperty("javax.net.ssl.trustStore", cacertLocation); System.setProperty("javax.net.ssl.trustStorePassword", cacertPassword); }
排查方向
- 连接池会话过期:检查Spring WS是否启用连接复用,目标服务是否会定期回收会话,导致复用的连接因会话过期触发401。可配置连接池的过期时间,或禁用连接复用测试。
- SSL属性加载时机:当前通过
@Bean设置系统属性,可能存在加载顺序问题,后续新建连接未正确读取SSL配置。建议在应用启动初期(如ApplicationListener)设置属性,或改用SpringSslBundle配置SSL。 - 服务器时间同步:Linux服务器与目标服务时间偏差过大,可能导致会话或Token过期校验失败。检查服务器时区与时间是否和目标服务同步。
- 异常捕获不完整:客户端仅打印异常字符串,遗漏关键堆栈信息。修改日志为打印完整堆栈,排查是否存在请求头构建失败的隐藏异常。
- Linux环境SSL差异:Windows与Linux默认信任库不同,检查自定义信任库文件权限是否可读,或目标服务支持的SSL协议/加密套件与Linux客户端是否兼容,可手动指定SSL协议版本测试。
内容的提问来源于stack exchange,提问作者Scott A. Levinson
相关产品推荐
相关产品推荐

