Skip to content

Commit 1100939

Browse files
committed
SWS-357
1 parent 55e6e3a commit 1100939

File tree

3 files changed

+97
-22
lines changed

3 files changed

+97
-22
lines changed

core/src/main/java/org/springframework/ws/soap/axiom/AxiomSoapMessage.java

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.io.IOException;
2020
import java.io.OutputStream;
21+
import java.io.StringWriter;
22+
import java.io.UnsupportedEncodingException;
2123
import java.util.Iterator;
2224
import javax.activation.DataHandler;
2325
import javax.xml.stream.XMLStreamException;
@@ -26,6 +28,7 @@
2628
import org.apache.axiom.om.OMElement;
2729
import org.apache.axiom.om.OMException;
2830
import org.apache.axiom.om.OMOutputFormat;
31+
import org.apache.axiom.om.impl.MIMEOutputUtils;
2932
import org.apache.axiom.om.impl.MTOMConstants;
3033
import org.apache.axiom.soap.SOAPBody;
3134
import org.apache.axiom.soap.SOAPEnvelope;
@@ -212,22 +215,34 @@ public void writeTo(OutputStream outputStream) throws IOException {
212215
OMOutputFormat format = new OMOutputFormat();
213216
format.setCharSetEncoding(charsetEncoding);
214217
format.setSOAP11(getVersion() == SoapVersion.SOAP_11);
215-
if (!attachments.getContentIDSet().isEmpty()) {
216-
format.setDoingSWA(true);
218+
boolean hasAttachments = !attachments.getContentIDSet().isEmpty();
219+
if (hasAttachments) {
220+
if (isXopPackage()) {
221+
format.setDoOptimize(true);
222+
}
223+
else {
224+
format.setDoingSWA(true);
225+
}
217226
}
218227
if (outputStream instanceof TransportOutputStream) {
219228
TransportOutputStream transportOutputStream = (TransportOutputStream) outputStream;
220229
String contentType = format.getContentType();
221-
contentType += "; charset=\"" + charsetEncoding + "\"";
230+
if (!hasAttachments) {
231+
contentType += "; charset=\"" + charsetEncoding + "\"";
232+
}
222233
transportOutputStream.addHeader(TransportConstants.HEADER_CONTENT_TYPE, contentType);
223234
transportOutputStream.addHeader(TransportConstants.HEADER_SOAP_ACTION, soapAction);
224235
}
225-
226-
if (payloadCaching) {
227-
axiomMessage.serialize(outputStream, format);
236+
if (!(format.isOptimized()) & format.isDoingSWA()) {
237+
writeSwAMessage(outputStream, format);
228238
}
229239
else {
230-
axiomMessage.serializeAndConsume(outputStream, format);
240+
if (payloadCaching) {
241+
axiomMessage.serialize(outputStream, format);
242+
}
243+
else {
244+
axiomMessage.serializeAndConsume(outputStream, format);
245+
}
231246
}
232247
outputStream.flush();
233248
}
@@ -239,6 +254,19 @@ public void writeTo(OutputStream outputStream) throws IOException {
239254
}
240255
}
241256

257+
private void writeSwAMessage(OutputStream outputStream, OMOutputFormat format)
258+
throws XMLStreamException, UnsupportedEncodingException {
259+
StringWriter writer = new StringWriter();
260+
SOAPEnvelope envelope = axiomMessage.getSOAPEnvelope();
261+
if (payloadCaching) {
262+
envelope.serialize(writer, format);
263+
}
264+
else {
265+
envelope.serializeAndConsume(writer, format);
266+
}
267+
MIMEOutputUtils.writeSOAPWithAttachmentsMessage(writer, outputStream, attachments, format);
268+
}
269+
242270
public String toString() {
243271
StringBuffer buffer = new StringBuffer("AxiomSoapMessage");
244272
if (payloadCaching) {

core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateIntegrationTest.java

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
import java.util.Enumeration;
2121
import java.util.Iterator;
2222
import java.util.StringTokenizer;
23+
import javax.activation.CommandMap;
24+
import javax.activation.DataHandler;
25+
import javax.activation.MailcapCommandMap;
26+
import javax.mail.util.ByteArrayDataSource;
2327
import javax.servlet.ServletConfig;
2428
import javax.servlet.ServletException;
2529
import javax.servlet.http.HttpServlet;
@@ -57,8 +61,10 @@
5761
import org.springframework.oxm.Unmarshaller;
5862
import org.springframework.oxm.XmlMappingException;
5963
import org.springframework.util.StringUtils;
64+
import org.springframework.ws.WebServiceMessage;
6065
import org.springframework.ws.client.WebServiceTransportException;
6166
import org.springframework.ws.pox.dom.DomPoxMessageFactory;
67+
import org.springframework.ws.soap.SoapMessage;
6268
import org.springframework.ws.soap.SoapMessageFactory;
6369
import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;
6470
import org.springframework.ws.soap.client.SoapFaultClientException;
@@ -72,12 +78,18 @@ public class WebServiceTemplateIntegrationTest extends XMLTestCase {
7278

7379
private static Server jettyServer;
7480

75-
private String messagePayload;
81+
private String messagePayload = "<root xmlns='http://springframework.org/spring-ws'><child/></root>";
7682

7783
public static Test suite() {
7884
return new ServerTestSetup(new TestSuite(WebServiceTemplateIntegrationTest.class));
7985
}
8086

87+
/*
88+
public void testSaaj() throws Exception {
89+
doSoap(new SaajSoapMessageFactory(MessageFactory.newInstance()));
90+
}
91+
*/
92+
8193
public void testAxiom() throws Exception {
8294
doSoap(new AxiomSoapMessageFactory());
8395
}
@@ -123,10 +135,10 @@ private void doSoap(SoapMessageFactory messageFactory) throws Exception {
123135
notFound();
124136
fault();
125137
faultNonCompliant();
138+
attachment();
126139
}
127140

128141
private void sendSourceAndReceiveToResult() throws SAXException, IOException {
129-
messagePayload = "<root xmlns='http://springframework.org/spring-ws'><child/></root>";
130142
StringResult result = new StringResult();
131143
boolean b = template.sendSourceAndReceiveToResult("http://localhost:8888/soap/echo",
132144
new StringSource(messagePayload), result);
@@ -240,6 +252,19 @@ private void faultNonCompliant() {
240252
}
241253
}
242254

255+
private void attachment() {
256+
template.sendSourceAndReceiveToResult("http://localhost:8888/soap/attachment", new StringSource(messagePayload),
257+
new WebServiceMessageCallback() {
258+
259+
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
260+
SoapMessage soapMessage = (SoapMessage) message;
261+
final String attachmentContent = "content";
262+
soapMessage.addAttachment("attachment-1",
263+
new DataHandler(new ByteArrayDataSource(attachmentContent, "text/plain")));
264+
}
265+
}, new StringResult());
266+
}
267+
243268
/** Servlet that returns and error message for a given status code. */
244269
private static class ErrorServlet extends HttpServlet {
245270

@@ -284,7 +309,7 @@ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws Serv
284309
/** Abstract SOAP Servlet */
285310
private abstract static class AbstractSoapServlet extends HttpServlet {
286311

287-
protected MessageFactory msgFactory = null;
312+
protected MessageFactory messageFactory = null;
288313

289314
private int sc = -1;
290315

@@ -295,7 +320,7 @@ public void setSc(int sc) {
295320
public void init(ServletConfig servletConfig) throws ServletException {
296321
super.init(servletConfig);
297322
try {
298-
msgFactory = MessageFactory.newInstance();
323+
messageFactory = MessageFactory.newInstance();
299324
}
300325
catch (SOAPException ex) {
301326
throw new ServletException("Unable to create message factory" + ex.getMessage());
@@ -305,7 +330,7 @@ public void init(ServletConfig servletConfig) throws ServletException {
305330
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
306331
try {
307332
MimeHeaders headers = getHeaders(req);
308-
SOAPMessage request = msgFactory.createMessage(headers, req.getInputStream());
333+
SOAPMessage request = messageFactory.createMessage(headers, req.getInputStream());
309334
SOAPMessage reply = onMessage(request);
310335
if (sc != -1) {
311336
resp.setStatus(sc);
@@ -326,7 +351,7 @@ else if (sc == -1) {
326351
}
327352
}
328353
catch (Exception ex) {
329-
throw new ServletException("SAAJ POST failed " + ex.getMessage());
354+
throw new ServletException("SAAJ POST failed " + ex.getMessage(), ex);
330355
}
331356
}
332357

@@ -373,13 +398,21 @@ protected SOAPMessage onMessage(SOAPMessage message) throws SOAPException {
373398
private static class SoapFaultServlet extends AbstractSoapServlet {
374399

375400
protected SOAPMessage onMessage(SOAPMessage message) throws SOAPException {
376-
SOAPMessage response = msgFactory.createMessage();
401+
SOAPMessage response = messageFactory.createMessage();
377402
SOAPBody body = response.getSOAPBody();
378403
body.addFault(new QName("http://schemas.xmlsoap.org/soap/envelope/", "Server"), "Server fault");
379404
return response;
380405
}
381406
}
382407

408+
private static class AttachmentsServlet extends AbstractSoapServlet {
409+
410+
protected SOAPMessage onMessage(SOAPMessage message) throws SOAPException {
411+
assertEquals("No attachments found", 1, message.countAttachments());
412+
return null;
413+
}
414+
}
415+
383416
/** A custom TestSetup to make sure that setUp() and tearDown() are only called once. */
384417
private static class ServerTestSetup extends TestSetup {
385418

@@ -388,6 +421,8 @@ private ServerTestSetup(Test test) {
388421
}
389422

390423
protected void setUp() throws Exception {
424+
removeXmlDataContentHandler();
425+
391426
jettyServer = new Server(8888);
392427
Context jettyContext = new Context(jettyServer, "/");
393428
jettyContext.addServlet(new ServletHolder(new EchoSoapServlet()), "/soap/echo");
@@ -396,12 +431,24 @@ protected void setUp() throws Exception {
396431
badRequestFault.setSc(400);
397432
jettyContext.addServlet(new ServletHolder(badRequestFault), "/soap/badRequestFault");
398433
jettyContext.addServlet(new ServletHolder(new NoResponseSoapServlet()), "/soap/noResponse");
434+
jettyContext.addServlet(new ServletHolder(new AttachmentsServlet()), "/soap/attachment");
399435
jettyContext.addServlet(new ServletHolder(new PoxServlet()), "/pox");
400436
jettyContext.addServlet(new ServletHolder(new ErrorServlet(404)), "/errors/notfound");
401437
jettyContext.addServlet(new ServletHolder(new ErrorServlet(500)), "/errors/server");
402438
jettyServer.start();
403439
}
404440

441+
/**
442+
* A workaround for the faulty XmlDataContentHandler in the SAAJ RI, which cannot handle mime types such as
443+
* "text/xml; charset=UTF-8", causing issues with Axiom. We basically reset the command map
444+
*/
445+
private void removeXmlDataContentHandler() throws SOAPException {
446+
MessageFactory messageFactory = MessageFactory.newInstance();
447+
SOAPMessage message = messageFactory.createMessage();
448+
message.createAttachmentPart();
449+
CommandMap.setDefaultCommandMap(new MailcapCommandMap());
450+
}
451+
405452
protected void tearDown() throws Exception {
406453
jettyServer.stop();
407454
}

parent/pom.xml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -432,20 +432,20 @@
432432
<version>1.2.7</version>
433433
<exclusions>
434434
<exclusion>
435-
<groupId>jaxen</groupId>
436-
<artifactId>jaxen</artifactId>
435+
<groupId>org.apache.geronimo.specs</groupId>
436+
<artifactId>geronimo-activation_1.1_spec</artifactId>
437437
</exclusion>
438438
<exclusion>
439-
<groupId>javax.mail</groupId>
440-
<artifactId>mail</artifactId>
439+
<groupId>org.apache.geronimo.specs</groupId>
440+
<artifactId>geronimo-javamail_1.4_spec</artifactId>
441441
</exclusion>
442442
<exclusion>
443-
<groupId>xml-apis</groupId>
444-
<artifactId>xml-apis</artifactId>
443+
<groupId>junit</groupId>
444+
<artifactId>junit</artifactId>
445445
</exclusion>
446446
<exclusion>
447-
<groupId>org.codehaus.woodstox</groupId>
448-
<artifactId>wstx-asl</artifactId>
447+
<groupId>org.apache.geronimo.specs</groupId>
448+
<artifactId>geronimo-stax-api_1.0_spec</artifactId>
449449
</exclusion>
450450
</exclusions>
451451
</dependency>

0 commit comments

Comments
 (0)