luisbandalap

luisbandalap / ASimpleSOAPClient.java

Last active 1 hour ago

Like 0

from https://gist.github.com/luisbandalap/21698dd3197f01e0527b28dbab6d889b

ASimpleSOAPClient.java Raw
1package com.kdstudio.snippets.soap.client;
2
3import java.io.ByteArrayInputStream;
4import java.io.IOException;
5import java.io.InputStream;
6import java.util.HashMap;
7import java.util.List;
8import java.util.Map;
9
10import javax.xml.parsers.DocumentBuilderFactory;
11import javax.xml.parsers.ParserConfigurationException;
12import javax.xml.soap.MessageFactory;
13import javax.xml.soap.MimeHeaders;
14import javax.xml.soap.SOAPBody;
15import javax.xml.soap.SOAPConnection;
16import javax.xml.soap.SOAPConnectionFactory;
17import javax.xml.soap.SOAPConstants;
18import javax.xml.soap.SOAPElement;
19import javax.xml.soap.SOAPEnvelope;
20import javax.xml.soap.SOAPException;
21import javax.xml.soap.SOAPHeader;
22import javax.xml.soap.SOAPMessage;
23import javax.xml.soap.SOAPPart;
24
25import org.slf4j.Logger;
26import org.slf4j.LoggerFactory;
27import org.w3c.dom.Document;
28import org.xml.sax.SAXException;
29
30/**
31 * This is an example of a simple SOAP Client class to send request body to a
32 * SOAP Server.
33 *
34 * Useful when you want to test a SOAP server and you don't want to generate all
35 * SOAP client class from the WSDL.
36 *
37 * @author kdelfour
38 * @modified luisbandalap
39 */
40public final class ASimpleSOAPClient {
41
42 // Default logger
43 private static final Logger LOGGER = LoggerFactory.getLogger(ASimpleSOAPClient.class);
44 private static final SOAPConnectionFactory SOAPCONNECTIONFACTORY;
45 private static final String AGENT_HEADER_NAME = "User-Agent";
46 private static final String SOAPACTION_HEADER_NAME = "SOAPAction";
47 private static final String AGENT_STRING = "Java/ASimpleSOAPClient-2.0";
48
49 static {
50 try {
51 synchronized (ASimpleSOAPClient.class) {
52 SOAPCONNECTIONFACTORY = SOAPConnectionFactory.newInstance();
53 }
54 } catch (UnsupportedOperationException | SOAPException ex) {
55 LOGGER.error("Error when connection factory was created", ex);
56 throw new RuntimeException("Error when connection factory was created", ex);
57 }
58 }
59
60 // The SOAP server URI
61 private final String uriSOAPServer;
62 private final String uriSOAPAction;
63 private final String SOAPProtocol;
64
65 // The SOAP connection
66 private final SOAPConnection soapConnection;
67
68 // Factories
69 private final MessageFactory messageFactory;
70 private final DocumentBuilderFactory builderFactory;
71
72 // Custom namespaces and headers definitions
73 private final Map<String, String> envelopeNamespaces;
74 private final Map<String, String> headerNamespaces;
75 private final Map<String, String> bodyNamespaces;
76 private final Map<String, List<String>> defaultHttpHeaders;
77
78 /**
79 * A constructor who create a SOAP connection
80 *
81 * @param url the SOAP server URI
82 */
83 public ASimpleSOAPClient(final String url) {
84 this(url, null, null);
85 }
86
87 /**
88 * A constructor who create a SOAP connection
89 *
90 * @param url the SOAP server URI
91 * @param operation the SOAP Action
92 */
93 public ASimpleSOAPClient(final String url, final String operation) {
94 this(url, operation, null);
95 }
96
97 /**
98 * A constructor who create a SOAP connection
99 *
100 * @param url the SOAP server URI
101 * @param operation the SOAP Action
102 * @param soapProtocol the SOAP protocol version
103 */
104 public ASimpleSOAPClient(final String url, final String operation, final String soapProtocol) {
105 //We set properties
106 this.uriSOAPServer = url;
107 this.uriSOAPAction = operation;
108 this.envelopeNamespaces = new HashMap<>();
109 this.headerNamespaces = new HashMap<>();
110 this.bodyNamespaces = new HashMap<>();
111 this.defaultHttpHeaders = new HashMap<>();
112 final String settedProtocol = soapProtocol != null ? soapProtocol : SOAPConstants.SOAP_1_1_PROTOCOL;
113 switch (settedProtocol) {
114 case SOAPConstants.SOAP_1_1_PROTOCOL:
115 case SOAPConstants.SOAP_1_2_PROTOCOL:
116 SOAPProtocol = settedProtocol;
117 break;
118 default:
119 throw new RuntimeException(soapProtocol + " is not a valid SOAP protocol version");
120 }
121
122 //We create the XML document factory
123 builderFactory = DocumentBuilderFactory.newInstance();
124 builderFactory.setNamespaceAware(true);
125
126 //We create the SOAP Connection and the Message Factory
127 try {
128 soapConnection = SOAPCONNECTIONFACTORY.createConnection();
129 messageFactory = MessageFactory.newInstance(this.SOAPProtocol);
130 } catch (Exception e) {
131 LOGGER.error("Error when endpoint was created", e);
132 throw new RuntimeException("Error when endpoint was created", e);
133 }
134 }
135
136 /**
137 * Send a SOAP request for a specific operation
138 *
139 * @param xmlRequestBody the body of the SOAP message
140 * @param xmlRequestHeader the header for your SOAP message
141 * @param operation the operation from the SOAP server invoked
142 * @param customHttpHeaders
143 * @return a response from the server
144 * @throws SOAPException
145 * @throws ParserConfigurationException
146 * @throws IOException
147 * @throws SAXException
148 */
149 public SOAPMessage sendMessageToSOAPServer(final String xmlRequestBody, final String xmlRequestHeader, final String operation, final Map<String, List<String>> customHttpHeaders)
150 throws SOAPException, SAXException, IOException, ParserConfigurationException {
151
152 // Send SOAP Message to SOAP Server
153 final SOAPElement soapBody = stringToSOAPElement(xmlRequestBody);
154 final SOAPElement soapHeader = xmlRequestHeader != null ? stringToSOAPElement(xmlRequestHeader) : null;
155 final SOAPMessage soapRequest = createSOAPRequest(soapBody, soapHeader, operation, customHttpHeaders);
156 final SOAPMessage soapResponse = soapConnection.call(soapRequest, uriSOAPServer);
157
158 // Print SOAP Response
159 LOGGER.info("Response SOAP Message : " + soapResponse.toString());
160 return soapResponse;
161 }
162
163 public SOAPMessage sendMessageToSOAPServer(String xmlRequestBody, String xmlRequestHeader, final Map<String, List<String>> customHttpHeaders)
164 throws SOAPException, SAXException, IOException, ParserConfigurationException {
165 return sendMessageToSOAPServer(xmlRequestBody, xmlRequestHeader, uriSOAPAction, customHttpHeaders);
166 }
167
168 public SOAPMessage sendMessageToSOAPServer(final Document bodyDocument, final Document headerDocument, final String operation, final Map<String, List<String>> customHttpHeaders)
169 throws SOAPException, SAXException, IOException, ParserConfigurationException {
170
171 // Send SOAP Message to SOAP Server
172 final SOAPElement soapBody = documentToSOAPElement(bodyDocument);
173 final SOAPElement soapHeader = headerDocument != null ? documentToSOAPElement(headerDocument) : null;
174 final SOAPMessage soapRequest = createSOAPRequest(soapBody, soapHeader, operation, customHttpHeaders);
175 final SOAPMessage soapResponse = soapConnection.call(soapRequest, uriSOAPServer);
176 // Print SOAP Response
177 LOGGER.info("Response SOAP Message : " + soapResponse.toString());
178 return soapResponse;
179 }
180
181 public SOAPMessage sendMessageToSOAPServer(final Document bodyDocument, final Document bodyHeader, final Map<String, List<String>> customHttpHeaders)
182 throws SOAPException, SAXException, IOException, ParserConfigurationException {
183 return sendMessageToSOAPServer(bodyDocument, bodyHeader, uriSOAPAction, customHttpHeaders);
184 }
185
186 /**
187 * Create a SOAP request
188 *
189 * @param body the body of the SOAP message
190 * @param header the header for your SOAP message
191 * @param operation the operation from the SOAP server invoked
192 * @return the SOAP message request completed
193 * @throws SOAPException
194 */
195 private SOAPMessage createSOAPRequest(final SOAPElement body, final SOAPElement header, final String operation, final Map<String, List<String>> customHttpHeaders)
196 throws SOAPException {
197 final SOAPMessage soapMessage = messageFactory.createMessage();
198 final SOAPPart soapPart = soapMessage.getSOAPPart();
199
200 // SOAP Envelope
201 final SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
202 if (envelopeNamespaces != null && !envelopeNamespaces.isEmpty()) {
203 for (final String prefixKey : envelopeNamespaces.keySet()) {
204 final String namespace = envelopeNamespaces.get(prefixKey);
205 soapEnvelope.addNamespaceDeclaration(prefixKey, namespace);
206 }
207 }
208
209 // SOAP Header
210 final SOAPHeader soapHeader = soapEnvelope.getHeader();
211 if (headerNamespaces != null && !headerNamespaces.isEmpty()) {
212 for (final String prefixKey : headerNamespaces.keySet()) {
213 final String namespace = headerNamespaces.get(prefixKey);
214 soapHeader.addNamespaceDeclaration(prefixKey, namespace);
215 }
216 }
217 if (header != null) {
218 soapHeader.addChildElement(header);
219 }
220
221 // SOAP Body
222 final SOAPBody soapBody = soapEnvelope.getBody();
223 if (bodyNamespaces != null && !bodyNamespaces.isEmpty()) {
224 for (final String prefixKey : bodyNamespaces.keySet()) {
225 final String namespace = bodyNamespaces.get(prefixKey);
226 soapBody.addNamespaceDeclaration(prefixKey, namespace);
227 }
228 }
229 soapBody.addChildElement(body);
230
231 // Mime Headers
232 final MimeHeaders headers = soapMessage.getMimeHeaders();
233 for (final String headKey : defaultHttpHeaders.keySet()) {
234 final List<String> headValues = defaultHttpHeaders.get(headKey);
235 if (headers.getHeader(headKey) != null && headers.getHeader(headKey).length > 0) {
236 headers.removeHeader(headKey);
237 }
238 for (final String headValue : headValues) {
239 headers.addHeader(headKey, headValue);
240 }
241 }
242
243 if (customHttpHeaders != null && !customHttpHeaders.isEmpty()) {
244 for (final String headKey : customHttpHeaders.keySet()) {
245 final List<String> headValues = customHttpHeaders.get(headKey);
246 if (headers.getHeader(headKey) != null && headers.getHeader(headKey).length > 0) {
247 headers.removeHeader(headKey);
248 }
249 for (final String headValue : headValues) {
250 headers.addHeader(headKey, headValue);
251 }
252 }
253 }
254
255 //We set operation if it is not set from http headers
256 if (operation != null) {
257 if (headers.getHeader(SOAPACTION_HEADER_NAME) != null && headers.getHeader(SOAPACTION_HEADER_NAME).length > 0) {
258 headers.removeHeader(SOAPACTION_HEADER_NAME);
259 }
260 headers.addHeader(SOAPACTION_HEADER_NAME, operation);
261 }
262
263 //We set user-agent if it is not set from http headers
264 if (!defaultHttpHeaders.containsKey(AGENT_HEADER_NAME)) {
265 headers.removeHeader(AGENT_HEADER_NAME);
266 headers.addHeader(AGENT_HEADER_NAME, AGENT_STRING);
267 }
268 soapMessage.saveChanges();
269
270 return soapMessage;
271 }
272
273 /**
274 * Transform a String to a SOAP element
275 *
276 * @param xmlRequestBody the string body representation
277 * @return a SOAP element
278 * @throws SOAPException
279 * @throws SAXException
280 * @throws IOException
281 * @throws ParserConfigurationException
282 */
283 private SOAPElement stringToSOAPElement(final String xmlRequestBody)
284 throws SOAPException, SAXException, IOException, ParserConfigurationException {
285 // Load the XML text into a DOM Document
286 try (final InputStream stream = new ByteArrayInputStream(xmlRequestBody.getBytes());) {
287 final Document doc = builderFactory.newDocumentBuilder().parse(stream);
288 // This returns the SOAPBodyElement that contains ONLY the Payload
289 return documentToSOAPElement(doc);
290 }
291 }
292
293 private SOAPElement documentToSOAPElement(final Document document)
294 throws SOAPException, SAXException, IOException,
295 ParserConfigurationException {
296 // Use SAAJ to convert Document to SOAPElement
297 // Create SoapMessage
298 final SOAPMessage message = messageFactory.createMessage();
299 final SOAPBody soapBody = message.getSOAPBody();
300
301 // This returns the SOAPBodyElement that contains ONLY the Payload
302 return soapBody.addDocument(document);
303 }
304
305 public String getUriSOAPServer() {
306 return uriSOAPServer;
307 }
308
309 public String getUriSOAPAction() {
310 return uriSOAPAction;
311 }
312
313 public Map<String, String> getEnvelopeNamespaces() {
314 return envelopeNamespaces;
315 }
316
317 public Map<String, String> getHeaderNamespaces() {
318 return headerNamespaces;
319 }
320
321 public Map<String, String> getBodyNamespaces() {
322 return bodyNamespaces;
323 }
324
325 public Map<String, List<String>> getDefaultHttpHeaders() {
326 return defaultHttpHeaders;
327 }
328}
329