INT-3974: Document SOAP Header Mapping

JIRA: https://jira.spring.io/browse/INT-3974

Polishing according PR comments
This commit is contained in:
Gary Russell
2016-03-24 11:50:39 -04:00
committed by Artem Bilan
parent 8db0ad3ae6
commit 8c95a0c2af
2 changed files with 101 additions and 4 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,21 +16,33 @@
package org.springframework.integration.ws;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.ByteArrayInputStream;
import java.util.Iterator;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.dom.DOMSource;
import org.junit.Test;
import org.w3c.dom.NodeList;
import org.springframework.ws.soap.SoapHeader;
import org.springframework.ws.soap.SoapHeaderElement;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.soap.saaj.SaajSoapMessage;
/**
* @author Gary Russell
@@ -78,6 +90,52 @@ public class DefaultSoapHeaderMapperTests {
assertSame(soapHeaderElement, headers.get("x:elem"));
}
@Test
public void testRealSoapHeader() throws Exception {
String soap =
"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+ "<soapenv:Header>"
+ "<auth>"
+ "<username>user</username>"
+ "<password>pass</password>"
+ "</auth>"
+ "<bar>BAR</bar>"
+ "<baz>BAZ</baz>"
+ "<qux>qux</qux>"
+ "</soapenv:Header>"
+ "<soapenv:Body>"
+ "<foo>foo</foo>"
+ "</soapenv:Body>"
+ "</soapenv:Envelope>";
SOAPMessage message = MessageFactory.newInstance()
.createMessage(new MimeHeaders(), new ByteArrayInputStream(soap.getBytes("UTF-8")));
SoapMessage soapMessage = new SaajSoapMessage(message);
DefaultSoapHeaderMapper mapper = new DefaultSoapHeaderMapper();
String authHeader = "auth";
mapper.setRequestHeaderNames(authHeader, "ba*");
Map<String, Object> headers = mapper.toHeadersFromRequest(soapMessage);
assertNotNull(headers.get(authHeader));
assertThat(headers.get(authHeader), instanceOf(SoapHeaderElement.class));
SoapHeaderElement header = (SoapHeaderElement) headers.get(authHeader);
DOMSource source = (DOMSource) header.getSource();
NodeList nodeList = source.getNode().getChildNodes();
assertEquals("username", nodeList.item(0).getNodeName());
assertEquals("user", nodeList.item(0).getFirstChild().getNodeValue());
assertEquals("password", nodeList.item(1).getNodeName());
assertEquals("pass", nodeList.item(1).getFirstChild().getNodeValue());
header = (SoapHeaderElement) headers.get("bar");
assertNotNull(header);
source = (DOMSource) header.getSource();
nodeList = source.getNode().getChildNodes();
assertEquals("BAR", nodeList.item(0).getNodeValue());
header = (SoapHeaderElement) headers.get("baz");
assertNotNull(header);
source = (DOMSource) header.getSource();
nodeList = source.getNode().getChildNodes();
assertEquals("BAZ", nodeList.item(0).getNodeValue());
assertNull(headers.get("qux"));
}
@Test
public void testExtractStandardHeadersNullSoapAction() {
DefaultSoapHeaderMapper mapper = new DefaultSoapHeaderMapper();

View File

@@ -173,12 +173,16 @@ The Spring Integration WebService Gateways will map the SOAP Action header autom
It will be copied by default to and from Spring Integration `MessageHeaders` using the
http://docs.spring.io/spring-integration/api/org/springframework/integration/ws/DefaultSoapHeaderMapper.html[DefaultSoapHeaderMapper].
Of course, you can pass in your own implementation of SOAP specific header mappers, as the gateways have respective properties to support that.
Of course, you can pass in your own implementation of SOAP specific header mappers, as the gateways have respective
properties to support that.
Any user-defined headers will NOT
be copied to or from an SOAP Message, unless explicitly specified by the _requestHeaderNames_ and/or
Any user-defined SOAP headers will NOT
be copied to or from a SOAP Message, unless explicitly specified by the _requestHeaderNames_ and/or
_replyHeaderNames_ properties of the `DefaultSoapHeaderMapper`.
When using the XML namespace for configuration, these properties can be set using the `mapped-request-headers` and
`mapped-reply-headers`, or a custom mapper can be provided using the `header-mapper` attribute.
TIP: When mapping user-defined headers, the values can also contain simple wildcard patterns (e.g. "foo*" or "*foo") to be matched.
For example, if you need to copy all user-defined headers simply use the wildcard character `*`.
@@ -196,3 +200,38 @@ Negated patterns get priority, so a list such as
IMPORTANT: If you have a user defined header that begins with `!` that you *do* wish to map, you need to escape it with
`\` thus: `STANDARD_REQUEST_HEADERS,\!myBangHeader` and it *WILL* be mapped.
Inbound SOAP headers (request headers for the inbound gateway, reply-headers for the outbound gateway) are mapped as
`SoapHeaderElement` objects.
The contents can be explored by accessing the `Source`:
[source, xml]
----
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<auth>
<username>user</username>
<password>pass</password>
</auth>
<bar>BAR</bar>
<baz>BAZ</baz>
<qux>qux</qux>
</soapenv:Header>
<soapenv:Body>
...
</soapenv:Body>
</soapenv:Envelope>
----
If `mapped-request-headers` is `"auth, ba*"`, the `auth`, `bar` and `baz` headers are mapped but `qux` is not.
[source, java]
----
...
SoapHeaderElement header = (SoapHeaderElement) headers.get("auth");
DOMSource source = (DOMSource) header.getSource();
NodeList nodeList = source.getNode().getChildNodes();
assertEquals("username", nodeList.item(0).getNodeName());
assertEquals("user", nodeList.item(0).getFirstChild().getNodeValue());
...
----