I'm trying to send an html email (with a text alternative) that includes an embedded/inline image using JavaMail.
I wanted to see what a properly formatted message looked like so I sent one using gmail with an inline image and below is the original source. It seems as if they are nesting body parts in the message. How can I replicate this EXACTLY using javamail. I found no way to put a Multipart inside of another Multipart.
MIME-Version: 1.0 Received: by 10.50.75.3 with HTTP; Thu, 23 Feb 2012
20:15:34 -0800 (PST) Date: Thu, 23 Feb 2012 20:15:34 -0800
Delivered-To: x#gmail.com Message-ID:
Subject: c From: Foo Bar To: Foo
Bar Content-Type: multipart/related;
boundary=e89a8f3b9b051e124104b9ae03fb
--e89a8f3b9b051e124104b9ae03fb Content-Type: multipart/alternative; boundary=e89a8f3b9b051e123604b9ae03fa
--e89a8f3b9b051e123604b9ae03fa Content-Type: text/plain; charset=ISO-8859-1
plain text content goes here
--e89a8f3b9b051e123604b9ae03fa Content-Type: text/html; charset=ISO-8859-1
--e89a8f3b9b051e123604b9ae03fa--
--e89a8f3b9b051e124104b9ae03fb Content-Type: image/png; name="logo.png" Content-Transfer-Encoding: base64 Content-ID:
X-Attachment-Id: ii_135ad92205fc1ace
iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAh0lEQVR42u3ZsQnAIBBGYVtHShVI
7ViprASXcw8HMCckEGyTkB98xWsE4WvOwnMhBG/tVrGaSOU0+Q5MVhMtdWAVBlY3HCyW+7nlbhqB
TiGAAAECBAhwMqB0AN8ANuUkgQzJvEPy1WP75C5AgAABAgQ4GXATAK4DUP8LOAsD87WGiIJriGj5
AwiiiyDxmymtAAAAAElFTkSuQmCC
--e89a8f3b9b051e124104b9ae03fb--
UPDATE:
Using the standard multipart inline image methods (like those linked to by lechlukasz) produces the following email, not quite what I need:
MIME-Version: 1.0 Received: by 10.236.146.106 with SMTP id
q70mr1894063yhj.0.1330071158663; Fri, 24 Feb 2012 00:12:38 -0800
(PST) Reply-To: Foo Bar Message-ID:
<20cf303bfc80f02cfa04b9b152db#google.com> Date: Fri, 24 Feb 2012
08:12:38 +0000 Subject: please oh please4 From: Foo Bar
To: Foo Bar Content-Type:
multipart/alternative; boundary=20cf303bfc80f02ce704b9b152d6
--20cf303bfc80f02ce704b9b152d6 Content-Type: text/plain; charset=UTF-8; format=flowed; delsp=yes Content-Transfer-Encoding:
base64
77+9UE5HDQoaDQoAAAANCklIRFIAAAAoAAAAKAgGAAAA77+977+977+9bQAAAO+/vUlEQVR477+9
77+977+977+9Ce+/vSAgDQoQRmFbR0oVSO+/vVjvv73vv70E77+9cw8HMCckEGzvv73vv70ffO+/ vWsE77+9a++/ve+/vXMhBG/vv71W77+977+9SO+/vTTvv70OTFYTLXVgFQZWNxws77+977+977+9 77+9bhrvv71OIe+/vQABAgQIcDLvv710AO+/vQA277+9JO+/vQzvv73vv71D77+977+9Y++/ve+/
vS5A77+9AAECBDgZcBMA77+9A1Dvv70LOAsD77+977+977+977+977+9a++/vWjvv70DCO+/ve+/ vSDvv73vv70p77+9AAAAAElFTkTvv71CYO+/vQ0K
--20cf303bfc80f02ce704b9b152d6 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
--20cf303bfc80f02ce704b9b152d6--
You put a Multipart in another Multipart by creating a MimeBodyPart, setting the content of that to the Multipart, and adding that body part to the first Multipart.
You mean something like that:
http://java.sun.com/developer/onlineTraining/JavaMail/contents.html#IncludingImagesWithHTML
Note that you need also modify your html to specify cid:identifier as image src.
Related
I am trying to create a multipart post to a URL with the following body:
Content-Disposition: form-data; name="json"
Content-Type: "application/json; charset=UTF-8"
{"input1":"data1","input2":"data2","input3":"data3"}
--APIMultipartPost
Content-Disposition: form-data; name="filePath"; filename="myFile.dat"
Content-Length: 381645
Content-Type: text/plain
Content-Transfer-Encoding: binary
<!-- SNIP -->
<!-- The OWL file was included here in plain text (without the SNIPs) -->
<!-- SNIP -->
I tried using MultipartEntityBuilder to create the multipart post, but probably I do something wrong with the parameters.
Can someone help me with the java code for this post?
Here is my code:
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost uploadFile = new HttpPost(URL);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("input1", "data1");
builder.addTextBody("input2", "data2");
builder.addTextBody("input3", "data3");
builder.addBinaryBody("file", new File("C:/myFile.dat"), ContentType.APPLICATION_OCTET_STREAM, "myFile.dat");
HttpEntity multipart = builder.build();
uploadFile.setEntity(multipart);
HttpResponse response = httpClient.execute(uploadFile);
and the error I get:
HttpResponseProxy{HTTP/1.1 422 Unprocessable Entity [Server: nginx/1.6.0, Date: Wed, 28 Jan 2015 19:29:42 GMT, Content-Type: application/json;charset=utf-8, Content-Length: 89, Connection: keep-alive, Status: 422 Unprocessable Entity, X-Rack-Cache: invalidate, pass, X-Content-Type-Options: nosniff] ResponseEntityProxy{[Content-Type: application/json;charset=utf-8,Content-Length: 89,Chunked: false]}}
Thank you!
The response 422 Unprocessable Entity says
The 422 (Unprocessable Entity) status code means the server
understands the content type of the request entity (hence a
415(Unsupported Media Type) status code is inappropriate), and the
syntax of the request entity is correct (thus a 400 (Bad Request)
status code is inappropriate) but was unable to process the contained
instructions. For example, this error condition may occur if an XML
request body contains well-formed (i.e., syntactically correct), but
semantically erroneous, XML instructions.
so as you can see the request you send doesn't fit with the specification of the controller/service that you POST to. If you use a tool like TCPMon you can actually intercept the request that you send and check how it looks like. When I do it with your code, it looks like
POST /url HTTP/1.1
Content-Length: 739
Content-Type: multipart/form-data; boundary=L2EqtNqIEXOWRCYYrYH8FSP1JAD65wz6c
Host: 127.0.0.1:8090
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.3.6 (java 1.5)
Accept-Encoding: gzip,deflate
--L2EqtNqIEXOWRCYYrYH8FSP1JAD65wz6c
Content-Disposition: form-data; name="input1"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
data1
--L2EqtNqIEXOWRCYYrYH8FSP1JAD65wz6c
Content-Disposition: form-data; name="input2"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
data2
--L2EqtNqIEXOWRCYYrYH8FSP1JAD65wz6c
Content-Disposition: form-data; name="input3"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
data3
--L2EqtNqIEXOWRCYYrYH8FSP1JAD65wz6c
Content-Disposition: form-data; name="file"; filename="myFile.dat"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
--L2EqtNqIEXOWRCYYrYH8FSP1JAD65wz6c--
which is not what you want. You only need a request with two parts, one is the json data and the other is the file.
So if you change your code as the following.
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost uploadFile = new HttpPost("http://localhost:8090/1");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
String jsonStr = "{\"input1\":\"data1\",\"input2\":\"data2\",\"input3\":\"data3\"}";
builder.addTextBody("json", jsonStr, ContentType.APPLICATION_JSON);
builder.addBinaryBody("file", new File("/path/to/file"),
ContentType.TEXT_PLAIN, "myFile.dat");
HttpEntity multipart = builder.build();
uploadFile.setEntity(multipart);
HttpResponse response = httpClient.execute(uploadFile);
You can provide a request like the following.
POST /url HTTP/1.1
Content-Length: 468
Content-Type: multipart/form-data; boundary=mN_bWsS4QQnlPJksvinB_WUpl2Qi6zVVElUEEBKh
Host: 127.0.0.1:8090
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.3.6 (java 1.5)
Accept-Encoding: gzip,deflate
--mN_bWsS4QQnlPJksvinB_WUpl2Qi6zVVElUEEBKh
Content-Disposition: form-data; name="json"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit
{"input1":"data1","input2":"data2","input3":"data3"}
--mN_bWsS4QQnlPJksvinB_WUpl2Qi6zVVElUEEBKh
Content-Disposition: form-data; name="file"; filename="myFile.dat"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: binary
--mN_bWsS4QQnlPJksvinB_WUpl2Qi6zVVElUEEBKh--
which is what you need.
For multipart request, the content-type has to be multipart/form-data, then you specify content-type for each content. You might want to refer to w3.org - Introduction to forms for the HTTP header examples.
I have a standard whole Mime source text string I need converted to either a Java or PHP object (or both if you want to show off !) so it can be manipulated in these platforms.
I have looked everywhere but only seem to be able to create from scratch.
So the below for example becomes an object that I can change headers or body parts, and the resend using the provided classes.
The require application for this is a distributed one, where I can supply customers a small java program while their local email app can point SMTP to, which I have done, and obtained Mime string as below.
I then want to be able to access and manipulate the various parts like headers and individual body parts before sending.
Surely there is some class or library which will offer this ? If necessary I can simply send the string to a PHP script if there is a suitable solution in PHP however its on a shared server so I cannot simply add PHP extensions.
Return-path: <tim#domain_a.com>
Envelope-to: XXXXXXXXXXXX
Delivery-date: Thu, 19 Sep 2013 09:54:17 +0100
Received: from XXXXXXXXXX [61.125]:62344 helo=[192.168.1.10])
by leopard.host-ns.co.uk with esmtpsa (TLSv1:DHE-RSA-CAMELLIA256-SHA:256)
(Exim 4.80.1)
(envelope-from <tXgham#dXm>)
id 1VMa09-000MOc-4T
for tiXham#daXcs.com; Thu, 19 Sep 2013 09:54:17 +0100
Message-ID: <523ABBB6.1080105#datXics.com>
Date: Thu, 19 Sep 2013 09:54:14 +0100
From: Txgham <tiXam#datXics.com>
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20130801 Thunderbird/17.0.8
MIME-Version: 1.0
To: TiXham <tiXam#daXics.com>
Subject: Re: Example
References: <523ABB49.50403#daXnics.com>
In-Reply-To: <523ABB49.50403#daXhanics.com>
Content-Type: multipart/alternative;
boundary="------------000900010104080404030103"
This is a multi-part message in MIME format.
--------------000900010104080404030103
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Example showing reply subpart and HTML <apage.html>
On 19/09/2013 09:52, TiXgham wrote:
> Example email
--------------000900010104080404030103
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
Example showing reply subpart and HTML <br>
<br>
<div class="moz-cite-prefix">On 19/09/2013 09:52, TiXam wrote:<br>
</div>
<blockquote cite="mid:523ABB49.50403#daXanics.com" type="cite">Example
email
<br>
</blockquote>
<br>
</body>
</html>
--------------000900010104080404030103--
This is out of date now and never did fully solve it. The issue was deemed as platform specific (iPhone) and not relevant after so much time.
i am trying to create an http file upload receiver in java
and i was looking at the post response of file upload in http
POST /upload?upload_progress_id=12344 HTTP/1.1
Host: localhost:3000
Content-Length: 1325
Origin: http://localhost:3000
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryePkpFF7tjBAqx29L
<other headers>
------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; name="MAX_FILE_SIZE"
100000
------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; name="uploadedfile"; filename="hello.o"
Content-Type: application/x-object
<file data>
------WebKitFormBoundaryePkpFF7tjBAqx29L--
if the boundary string will be a part of the file that is being uploaded (by coincidence) how can i detect it ? is that even possible?
Well, as section 4.1 of RFC 2388 states:
4.1 Boundary
As with other multipart types, a boundary is selected that does not occur in any of the data.
So I guess that your browser will probably be smart enough to choose an appropriate boundary.
Basically, the following is what the format of data look like (it should follow HTTP standard format)
Content-Type: multipart/form-data; boundary=--3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f
--3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f
Content-Disposition: form-data; name="foo1.jpg"; filename="foo1.jpg"
Content-Length: 5578
Content-Type: image/jpeg
<image data 1 omitted>
--3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f
Content-Disposition: form-data; name="foo2.jpg"; filename="foo2.jpg"
Content-Length: 327
Content-Type: image/jpeg
<image data 2 omitted>
--3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f--
You can take a look at this question which recommends using Apache Commons File upload
Greetings all...
I am hoping somebody can shed me some lights about the issue I am having.
Reading the Javadoc of MimeMessage's getInputStream(), it says "Return a decoded input stream for this Message's content"
However, this is not what I am experiencing. The output is not decoded. For instance, if I have a message a follows
Date: Wed, 24 Feb 2010 11:29:13 +1100
From: xxxxxxxxx
To: xxxxxxxxxxxx
Message-ID: <4B8472D9.5050901#xxxxxxxxx>
Subject: xxxxxxxxxxxxxxxxxx
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="------------000801030004000206000901"
Content-Transfer-Encoding: quoted-printable
Organization: xxxxxxxxxxxxxxxxxx
User-Agent: Thunderbird 2.0.0.23 (Windows/20090812)
This is a multi-part message in MIME format.
--------------000801030004000206000901
Content-Type: text/plain; charset=3DISO-8859-1; format=3Dflowed
Content-Transfer-Encoding: 7bit
!
--------------000801030004000206000901
Content-Type: text/plain;
name=3D"bla.bla"
Content-Transfer-Encoding: 8bit
Content-Disposition: inline;
filename=3D"bla.bla"
my.username =3D holly
my.host =3D molly
--------------000801030004000206000901--
Then, assuming that I have an object called 'm' constructed with the above content, then calling m.getInputStream() and dump the output to the screen shows those '=3D' charsets.
What did I do wrong?
If I used QPDecoderStream to decode the output of m.getInputStream() then of course the result will be correct. However, it defeat the purpose, because the Javadoc says getInputStream() returns a decoded input stream.
The issue here is that the message is malformed. You're not allowed to set Content-Transfer-Encoding to quoted-printable on a multipart part:
If a Content-Transfer-Encoding header field appears as part of a
message header, it applies to the entire body of that message. If a
Content-Transfer-Encoding header field appears as part of an entity's
headers, it applies only to the body of that entity. If an entity is
of type "multipart" the Content-Transfer-Encoding is not permitted to
have any value other than "7bit", "8bit" or "binary".
You could probably get the top-level MimeMessage's decoded content stream and instantiate a MimeMultipart from it, but that's just hacking around the fundamental problem of a broken message.