Missing Content-ID for attachments on Spring Webservice implementatiokn

As part of a J2EE product we have, we are now exposing some of it's features through a SOAP interface.

As there are many options, and many directly coupled to app server specific features, we tried to setup the most server independant coding possible, and thus, we selected spring webservices as our develepment framework.

Coding actually hasn't been an issue, but deploying in has been total mayhem!! We managed to correctly deploy it in JBoss 4.2 and IBM WAS 6.1, but somebody pinpointed us a server independent bug: content-id for attachments where not generated on the root node (see response.xml as output).

Any ideas of what's going on? Someday during this week I'll also have to test the WS on Weblogic, hoping that it won't suck as these 2 present do :(

PS: The attached code is the one used to "add" the attachment to the response (bug in jboss)
byte[] attach = getResults(proc);
		try {
			if (attach != null) {
				DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
				DocumentBuilder documentBuilder = documentBuilderFactory
				Document document = documentBuilder.newDocument();
				WebServiceMessage response = messageContext.getResponse();
				SaajSoapMessage soapMessage = (SaajSoapMessage) response;

				SoapBody soapBody = soapMessage.getEnvelope().getBody();
				Element resp = document.createElementNS(NS_URL, RESPONSE_NODE);
				resp.setPrefix(RESPONSE_NS_PREFFIX );

				DataSource dataSource = new ByteArrayDataSource(attach,
				DataHandler dataHandler = new DataHandler(dataSource);
				String filename = ATTACH_NAME;
				String operation = proc.getOperation();
				if (operation.startsWith("PDF")) {
					filename += ".pdf";
				} else if (operation.startsWith("XML")
						|| operation.equals("DOC_HIT_LIST")) {
					filename += ".xml";
				} else if (operation.equals("DOC_BY_ID")
						|| operation.equals("TXT")) {
					filename += ".txt";

				soapMessage.addAttachment(filename, dataHandler);
				transform(new DOMSource(document), soapBody.getPayloadResult());

		} catch (Exception e) {
			throw e;

Open in new window

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

gvasquez95Author Commented:
Solved WAS problem using hints from: http://forum.springsource.org/showthread.php?t=85558&highlight=websphere

But now I have the same problem on both App Servers: missing Content-ID
Which Spring version is this?
Back in the days there was no way to set it - http://www.techinfopad.com/spring/101200261-contentid-in-soap-attachment.html - amongst others was where the feature was promised...

Had you tried using AxiomSoapMessage instead of SAAJSoapMessage - that's the one I had been using with no issues (but you also set the content ID directly there)... No idea why the Saaj one fails though
gvasquez95Author Commented:
I've mánaged to add the attachment using saaj's method, but it's reference i'm afraid has to be arded manually though :(

this only works in WAS, as jboss seems to have XML jar conflicts....tomorrow i'll try it in weblogic
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

gvasquez95Author Commented:
spring 2.5.6 & spring-ws 1.5.9

This is the list of all JAR files currently in my WEB-INF/lib folder:

Ok - looks good enough
Looked at that code a bit more careful and:
soapMessage.addAttachment(filename, dataHandler);
Why are you passing the filename here?

That first parameter is supposed to be the content-id. Are you using the filename as a contentID? What happens if you do this:
Attachment attach = soapMessage.addAttachment(filename, dataHandler);

(where log is your way to be logging)

I suspect that this is null -as the content_ID should conform to RFC 2045

So try to use something like:
String contentID = filename + "@test.org"
String contentID = "<" + filename + "@test.org" + ">"

And see if this does not solve the issue

However - in the long term you will need to generate these somehow to be unique - so you might want to start looking at it. Let me see if I can find my old generateContentId :)

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Something like

String randomContentID = "<" + UUID.randomUUID().toString() + "@myown"+ ">";

Should do the trick for example. Or something like this. :) You might want to add your filename somewhere such as:

String randomContentID = "<" + UUID.randomUUID().toString() + "@"+ filename + ">";
gvasquez95Author Commented:
Thx Venabili, I wasn't aware of the RFC you mentioned, would it be OK if just add the '@' and our domain name to the filename? Filenames would be unique within the request as we are ALWAYS returning only one attachment, or do they have to be unique between requests, too? (I'm not the kind of guy that really understand what RFCs request to do ;) )
That is what I am not sure about now and I usually use random - haven't done anything with SOAP for a while so do not remember now why :(. You should be just fine with just unique inside of the request I think:)

yeah - using your domain name after @ is fine, make sure you do not miss <> also and do some tests (I do not think spring will add <> authomatically so you need to) . Let me know if you still have issues

Thinking on it again...
should be more than enough :)

http://www.w3.org/TR/SOAP-attachments kinda proves it to some extent.

Sorry for not seeing this yesterday - I actually glossed over the code and never saw that you are using the file name there :)
gvasquez95Author Commented:
just tested the "log" statement, and it outputs just the filename I entered, so the code is not complaining, but as you mentioned, standards are broken ;) I'll added the enclosing "<" and ">" and the mail-like suffix to it, and that should be standard compliant; but that wasn't actually the question I had, but I think I've solved it manually, as probably that was the only way to do it. I added the following to the response Node:

 <reports:file href="cid:file.pdf"/>

using attached code, that was the main issue: the reference to the already added contentId was missing.

Element ref = document.createElementNS(NS_URL, "file");
ref.setAttribute("href", "cid:" + filename);

Open in new window

gvasquez95Author Commented:
after adding the enclosing char, thinks look a bit misleading, but are they ok, or do I have to "escape" those  chars?

SOAP UI shows the response as the first code snippet, see that '<' has been converted to html representation < but '>' hasn't been touched...mmm

SOAPUI's http log shows a bit different see 2nd part of the snippet

are things OK that way, or should I treat those chars specially?
PART #1: response in SOAPUI

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
      <reports:QueryResponse xmlns:reports="http://altiuz.cl/reports/schemas">
         <reports:file href="cid:&lt;file.xml@altiuz.cl>"/>


Part #2: SOAPUI's http log

Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "HTTP/1.1 200 OK[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "SOAPAction: ""[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "Content-Type: multipart/related; boundary="----=_Part_0_894317902.1270138434221"; type="text/xml"[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "Content-Length: 1012[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "Content-Language: es-CL[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "Date: Thu, 01 Apr 2010 16:13:54 GMT[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "Server: WebSphere Application Server/6.1[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "------=_Part_0_894317902.1270138434221[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "Content-Type: text/xml; charset=utf-8[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><reports:QueryResponse xmlns:reports="http://altiuz.cl/reports/schemas"><reports:file href="cid:&lt;file.xml@altiuz.cl&gt;"/></reports:QueryResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "------=_Part_0_894317902.1270138434221[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "Content-Type: application/octet-stream[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "Content-ID: <file.xml@altiuz.cl>[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "Content-Transfer-Encoding: binary[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "<?xml version="1.0" encoding="ISO-8859-1"?><result><doc id="v7126-5203-5204-5205-RCA1-1FAAA-0-5145-0-807-85-79-0-1-0-%5E%01111111111%01201001%01RAZ%D3N+SOCIAL+EMPRESA+1%0100000000000000011111%011268409071"><indexes><PERIODO_ABONO>201001</PERIODO_ABONO><RAZON_SOCIAL>RAZ[0xc3][0x93]N SOCIAL EMPRESA 1</RAZON_SOCIAL><FECHA_CARGA>12/03/2010 15:51:11</FECHA_CARGA><RUT>111111111</RUT><NUM_CUENTA>00000000000000011111</NUM_CUENTA></indexes></doc></result>[\r][\n]"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "------=_Part_0_894317902.127"
Thu Apr 01 12:13:54 CLT 2010:DEBUG:<< "0138434221--"

Open in new window

What is SOAP UI? :) I think it is just visual thing and the log looks good to me

So can you try and see if this whole thing work? If not - we will need to teak a bit around < and > :)
Sorry - missed your previous comment

Basically the Missing Content ID is a message I see sometimes when my content_id is malformed. :)

Guess there was another issue there as well :) (which was not part of the code that you posted though)

anyway - things working now?
gvasquez95Author Commented:
I'll just have to wait to see, what the "consumer" of the webservice says..guessing that will happen somewhere next week, I'll keep you informed ;)
gvasquez95Author Commented:
SOAPU: http://www.soapui.org/

A great tool for WS testing.
Then I am almost sure it is a visual thing only :)

NEver used this - but it looks interesting. I am kinda old-school - I would simply put together a server/client to test :)

OK - good luck :)
gvasquez95Author Commented:
Actually needed answer to a different matter, but answer led to resolve other issues present.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Languages and Standards

From novice to tech pro — start learning today.