From 8c95a0c2afc895e0ab686ee53b5086eddef49602 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Thu, 24 Mar 2016 11:50:39 -0400 Subject: [PATCH] INT-3974: Document SOAP Header Mapping JIRA: https://jira.spring.io/browse/INT-3974 Polishing according PR comments --- .../ws/DefaultSoapHeaderMapperTests.java | 60 ++++++++++++++++++- src/reference/asciidoc/ws.adoc | 45 +++++++++++++- 2 files changed, 101 insertions(+), 4 deletions(-) diff --git a/spring-integration-ws/src/test/java/org/springframework/integration/ws/DefaultSoapHeaderMapperTests.java b/spring-integration-ws/src/test/java/org/springframework/integration/ws/DefaultSoapHeaderMapperTests.java index ae336b6a12..408b1b9ca9 100644 --- a/spring-integration-ws/src/test/java/org/springframework/integration/ws/DefaultSoapHeaderMapperTests.java +++ b/spring-integration-ws/src/test/java/org/springframework/integration/ws/DefaultSoapHeaderMapperTests.java @@ -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 = + "" + + "" + + "" + + "user" + + "pass" + + "" + + "BAR" + + "BAZ" + + "qux" + + "" + + "" + + "foo" + + "" + + ""; + 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 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(); diff --git a/src/reference/asciidoc/ws.adoc b/src/reference/asciidoc/ws.adoc index f81f7a0074..0439bb27fc 100644 --- a/src/reference/asciidoc/ws.adoc +++ b/src/reference/asciidoc/ws.adoc @@ -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] +---- + + + + user + pass + + BAR + BAZ + qux + + + ... + + +---- + +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()); +... +----