#java #spring-boot #web-services #soap
Вопрос:
Я использую Spring Boot и пытаюсь настроить шаблон веб-службы для добавления базовых заголовков аутентификации при каждом запросе SOAP.
Вот мой класс конфигурации:
@Configuration
public class SoapClientConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(SoapClientConfiguration.class);
private final DmsConfiguration dmsConfiguration;
public SoapClientConfiguration(DmsConfiguration dmsConfiguration) {
this.dmsConfiguration = dmsConfiguration;
}
/**
* Method for generating POJO objects from xml at pointed location
*
* @return Jaxb2Marshaller instance.
*/
@Bean
public Jaxb2Marshaller marshaller()
{
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan(dmsConfiguration.getJaxbPackageLocation());
return marshaller;
}
/**
* Configuring DMS web service client
*
* @param marshaller jaxb2 marshaller
* @return DmsWebServiceClient Object
*/
@Bean
public DmsWebServiceClient dmsWebServiceClient(Jaxb2Marshaller marshaller)
throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException
{
DmsWebServiceClient dmsWebServiceClient = new DmsWebServiceClient();
dmsWebServiceClient.setDefaultUri(
dmsConfiguration.getProtocol() "://" dmsConfiguration.getConsumerServicesUri()
);
dmsWebServiceClient.setMarshaller(marshaller);
dmsWebServiceClient.setUnmarshaller(marshaller);
dmsWebServiceClient.setMessageSender(defaultMessageSender());
return dmsWebServiceClient;
}
@Bean
public HttpComponentsMessageSender defaultMessageSender()
throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException
{
return new HttpComponentsMessageSender(createHttpClient());
}
@Bean
public HttpClient createHttpClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException
{
BasicHeader authHeader = new BasicHeader(
"Authorization", "Basic " dmsConfiguration.getBasicAuthenticationCredentials()
);
LOGGER.info("Web service credentials: {}", dmsConfiguration.getBasicAuthenticationCredentials());
List<BasicHeader> authHeaders = Collections.singletonList(authHeader);
RequestDefaultHeaders reqHeader = new RequestDefaultHeaders(authHeaders);
return HttpClients.custom()
.setSSLSocketFactory(sslConnectionSocketFactory())
.addInterceptorFirst(new HttpComponentsMessageSender.RemoveSoapHeadersInterceptor())
.addInterceptorLast(reqHeader)
.setDefaultHeaders(authHeaders)
.build();
}
public SSLConnectionSocketFactory sslConnectionSocketFactory()
throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException
{
return new SSLConnectionSocketFactory(sslContext(), NoopHostnameVerifier.INSTANCE);
}
public SSLContext sslContext() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException
{
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
return SSLContexts.custom()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build();
}
}
а вот конфигурация клиента:
public class DmsWebServiceClient extends WebServiceGatewaySupport {
private DmsCallbackConfiguration dmsCallbackConfiguration;
/**
* Getting or creating subject
*
* @param subject target subject
* @return GetOrCreateSubjectResponse Object
*/
public GetOrCreateSubjectResponse getOrCreateSubject(GetOrCreateSubjectRequest subject)
{
ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<GetOrCreateSubjectRequest> request = objectFactory.createGetOrCreateSubjectRequest(subject);
return (GetOrCreateSubjectResponse) getWebServiceTemplate()
.marshalSendAndReceive(request, new SoapActionCallback(dmsCallbackConfiguration.getCreateSubject()));
}
/**
* Getting or creating document
*
* @param document target document
* @return GetOrCreateDocumentResponse Object
*/
public GetOrCreateDocumentResponse getOrCreateDocument(GetOrCreateDocumentRequest document)
{
ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<GetOrCreateDocumentRequest> request = objectFactory.createGetOrCreateDocumentRequest(document);
return (GetOrCreateDocumentResponse) getWebServiceTemplate()
.marshalSendAndReceive(request, new SoapActionCallback(dmsCallbackConfiguration.getCreateDocument()));
}
/**
* Inserting attachment data
*
* @param attachment attachment input
* @return InsertAttachmentResponse Object
*/
public InsertAttachmentByDocumentIdResponse uploadAttachment(InsertAttachmentByDocumentIdRequest attachment)
{
ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<InsertAttachmentByDocumentIdRequest> request
= objectFactory.createInsertAttachmentByDocumentIdRequest(attachment);
return (InsertAttachmentByDocumentIdResponse) getWebServiceTemplate()
.marshalSendAndReceive(request, new SoapActionCallback(dmsCallbackConfiguration.getInsertAttachment()));
}
@Autowired
public void setDocumentSubjectConfiguration(DmsCallbackConfiguration dmsCallbackConfiguration) {
this.dmsCallbackConfiguration = dmsCallbackConfiguration;
}
}
Связь между службами работает нормально, но я получаю 401 несанкционированный каждый раз, когда отправляю запрос.
Вы хоть представляете, что не так с моим кодом?
Заранее благодарю вас!
P.S. Я настроил ведение журнала, и вот один пример запроса:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/>
<SOAP-ENV:Body><ns2:GetOrCreateSubjectRequest xmlns:ns2="http://schemas.datacontract.org/2004/07/WCFService" xmlns:ns3="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><ns2:Attributes><ns2:AttributeValue><ns2:IdAttribute>1084</ns2:IdAttribute><ns2:Value>test</ns2:Value></ns2:AttributeValue></ns2:Attributes><ns2:DefaultSettingsOverride>1</ns2:DefaultSettingsOverride><GetOrCreateSubjectRequest>7</GetOrCreateSubjectRequest><GetOrCreateSubjectRequest>1109953265147</GetOrCreateSubjectRequest><ns2:IdLanguage>2</ns2:IdLanguage><GetOrCreateSubjectRequest>1676</GetOrCreateSubjectRequest><ns2:IdUser>1304</ns2:IdUser><ns2:IdWorkflow>30</ns2:IdWorkflow><ns2:Name>Dosije klijenta</ns2:Name></ns2:GetOrCreateSubjectRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>