Forward an email(read using JavaMailApi) with Attachments by apache common java api - email

I'm reading messages from an Outlook webmail and getting a list of Messages('javax.mail.Message'). Now I want to forward these Messages to another email address using a java program.
private void sendTestMail(String from, String subject, String sentDate, Object object, Message message)
throws EmailException, Exception {
MultiPartEmail email = new MultiPartEmail();
email.setHostName(forwardHost);
email.addTo(mailRecipients(to));
email.setFrom(emailFrom);
email.setSubject(subject);
email.setMsg("Testing email by sahil.");
EmailAttachment attachment = new EmailAttachment();
attachment.setPath("c:\\sahil\\test.jpg");
attachment.setDisposition(EmailAttachment.ATTACHMENT);
attachment.setDescription("Picture_of_John");
attachment.setName("John.jpg");
email.attach(attachment);
MimeMultipart multiPart = getMimeMultipart(message);
email.addPart(multiPart);
email.send();
}
If I comment below two lines in above code then it works fine.
MimeMultipart multiPart = getMimeMultipart(message);
email.addPart(multiPart);
But with these two line I'm getting exception.
2020-04-20 15:41:44,271 ERROR com.st.ict.ols.service.impl.ReplyToMessageServiceImpl [main] Inner Exception occurred while processing individual message. Error stacktrace is[org.apache.commons.mail.EmailException: Sending the email to the following server failed : smtpapp1.sgp.st.com:25
at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1421)
at org.apache.commons.mail.Email.send(Email.java:1448)
at com.st.ict.ols.service.impl.ReplyToMessageServiceImpl.sendTestMail(ReplyToMessageServiceImpl.java:342)
at com.st.ict.ols.service.impl.ReplyToMessageServiceImpl.processMessage(ReplyToMessageServiceImpl.java:167)
at com.st.ict.ols.service.impl.MessageServiceImpl.processMessage(MessageServiceImpl.java:22)
at com.st.ict.ols.OlsMailSenderApplication.run(OlsMailSenderApplication.java:36)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:732)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:716)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:703)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:304)
at com.st.ict.ols.OlsMailSenderApplication.main(OlsMailSenderApplication.java:27)
Caused by: javax.mail.MessagingException: IOException while sending message;
nested exception is:
java.io.IOException: Exception writing Multipart
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1308)
at javax.mail.Transport.send0(Transport.java:255)
at javax.mail.Transport.send(Transport.java:124)
at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1411)
... 10 more
Caused by: java.io.IOException: Exception writing Multipart
at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:83)
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:884)
at javax.activation.DataHandler.writeTo(DataHandler.java:317)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1652)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:961)
at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:553)
at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:81)
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:884)
at javax.activation.DataHandler.writeTo(DataHandler.java:317)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1652)
at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1850)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1259)
... 13 more
Caused by: javax.mail.MessagingException: Empty multipart: multipart/mixed;
boundary="----=_Part_1_1176580790.1587377502798"
at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:548)
at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:81)
... 24 more
Code I've written to retrieve MimeMultipart from JavaMailApi's Message object to set in apache common's org.apache.commons.mail.MultiPartEmail Object using attach function.
public MimeMultipart getMimeMultipart(Message message) throws Exception {
Object content = message.getContent();
if (content instanceof String)
return null;
if (content instanceof MimeMultipart) {
MimeMultipart multiPartResult = new MimeMultipart();
MimeMultipart multiPart = (MimeMultipart) content;
List<BodyPart> result = new ArrayList<>();
for (int i = 0; i < multiPart.getCount(); i++) {
BodyPart bodyPart = (BodyPart) multiPart.getBodyPart(i);
result.addAll(getMimeMultipart(bodyPart));
}
for(BodyPart part:result) {
multiPart.addBodyPart(part);
}
return multiPartResult;
}
return null;
}
private List<BodyPart> getMimeMultipart(BodyPart part) throws Exception{
List<BodyPart> result = new ArrayList<>();
Object content = part.getContent();
if (content instanceof InputStream || content instanceof String) {
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()) || StringUtils.isNotBlank(part.getFileName())) {
result.add(part);
}
return result;
}
if (content instanceof MimeMultipart) {
MimeMultipart multipart = (MimeMultipart) content;
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart bodyPart = (BodyPart) multipart.getBodyPart(i);
result.addAll(getMimeMultipart(bodyPart));
}
}
return result;
}
I was able to forward email excluding attachments but facing issues forwarding with attachments/inline images.
Please help me with this issue.
I'm able to forward the complete message as an attachment, how to forward the message as it is.
MultiPartEmail email = new MultiPartEmail();
MimeMultipart mp = new MimeMultipart();
MimeBodyPart fmbp = new MimeBodyPart();
fmbp.setContent(message, "message/rfc822");
fmbp.setDisposition(Part.INLINE);
mp.addBodyPart(fmbp);
email.setContent(mp);
or if I use code
MimeMultipart mp = (MimeMultipart) message.getContent();
email.setContent(mp, message.getContentType());
I'm getting forwarded email like this
screenshot of forwarded encoded mail

Here the situation is reading mail from one mail server and sending the same message to another email id, within same application.
To achieve this, I used Java Mail API for both reading and sending.
Make sure to update the properties if you're using different host for both steps.
private void sendMailJavax(Message oldMessage) {
try {
// creating a new message using the older message
MimeMessage message = new MimeMessage((MimeMessage)oldMessage);
// updating properties as per sender Mailing API
message.getSession().getProperties().clear();
message.getSession().getProperties().setProperty("mail.smtp.host", forwardHost);
// setting appropriate headers. // make sure you don't append using .add methods.
message.setFrom(new InternetAddress(emailFrom));
message.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setReplyTo(new Address[] { new InternetAddress(replyToEmail)});
Transport.send(message);
System.out.println("Email Sent successfully....");
} catch (MessagingException mex) {
mex.printStackTrace();
}
}

Related

Mule ESB with CXF WSS4JOutInterceptor does not create a proper SOAPFault if fails

I'm using WSS4j CXF Out Interceptor in MULE to sign the SOAP response but if there is an error in this interceptor the SOAPFault is not generated properly. In fact the result is a blank body with status 200.
Problem:
If the out interceptor used to sign (WSS4JOutInterceptor) fails, it does not generates a proper SOAPFault (with status code 400/500) due to is executed in PRE_PROTOCOL and the http.status and response headers have already been written in the HttpResponse.
Cause
The SOAPFault is generated in a last phase in the interceptor chain (interceptor chain) so the HttpConnection is already open and the HttpResponse is being written, headers and status are set.
Detail
Mule version: 3.6.1 CE
CXF version: 2.5.9
WSS4j: 1.6.9
JVM: JDK7
The CXF inbound enpoint in mule calls to CxfInboundMessageProcessor. This class create the Exchange to execute the input interceptor chain , the mule flow and finally the output interceptor chain .
The most important phases that causes this error are the following:
PREPARE_SEND Opening of the connection
PRE_STREAM
PRE_PROTOCOL Misc protocol actions.->Here is executed *WSS4jOutInterceptor**
The output interceptor chain is executed in two phases, the mule interceptor MuleProtocolHeadersOutInterceptor (PRE_STREAM) pauses it. The rest of the output interceptor chain is executed when the HttpResponse is fully created.
When it is paused the execution return back to the first class CxfInboundMessageProcessor.
it is after that when the response is going to be created:
MuleMessage muleResMsg = responseEvent.getMessage();
muleResMsg.setPayload(getResponseOutputHandler(m));
The interface org.mule.api.transport.OutputHandler is used to delegate the SOAP object creation until the org.mule.transport.http.ResponseWriter is executed:
OutputHandler:
Here it can see how the method write continues with the output chain:
public void write(MuleEvent event, OutputStream out) throws IOException
{
Message outFaultMessage = m.getExchange().getOutFaultMessage();
Message outMessage = m.getExchange().getOutMessage();
Message contentMsg = null;
if (outFaultMessage != null && outFaultMessage.getContent(OutputStream.class) != null)
{
contentMsg = outFaultMessage;
}
else if (outMessage != null)
{
contentMsg = outMessage;
}
if (contentMsg == null)
{
return;
}
DelegatingOutputStream delegate = contentMsg.getContent(DelegatingOutputStream.class);
if (delegate.getOutputStream() instanceof ByteArrayOutputStream)
{
out.write(((ByteArrayOutputStream) delegate.getOutputStream()).toByteArray());
}
delegate.setOutputStream(out);
out.flush();
contentMsg.getInterceptorChain().resume();
}
org.mule.transport.http.HttpServerConnection
public void writeResponse(final HttpResponse response, Map<String,String> headers) throws IOException
{
if (response == null)
{
return;
}
if (!response.isKeepAlive())
{
Header header = new Header(HttpConstants.HEADER_CONNECTION, "close");
response.setHeader(header);
}
setKeepAlive(response.isKeepAlive());
addHeadersToHttpResponse(response, headers);
ResponseWriter writer = new ResponseWriter(this.out, encoding);
OutputStream outstream = this.out;
writer.println(response.getStatusLine());
Iterator item = response.getHeaderIterator();
while (item.hasNext())
{
Header header = (Header) item.next();
writer.print(header.toExternalForm());
}
writer.println();
writer.flush();
OutputHandler content = response.getBody();
if (content != null)
{
Header transferenc = response.getFirstHeader(HttpConstants.HEADER_TRANSFER_ENCODING);
if (transferenc != null)
{
response.removeHeaders(HttpConstants.HEADER_CONTENT_LENGTH);
if (transferenc.getValue().indexOf(HttpConstants.TRANSFER_ENCODING_CHUNKED) != -1)
{
outstream = new ChunkedOutputStream(outstream);
}
}
content.write(RequestContext.getEvent(), outstream);
if (outstream instanceof ChunkedOutputStream)
{
((ChunkedOutputStream) outstream).finish();
}
}
outstream.flush();
}
And here after httpResponse creation and set the headers is when the "body" is generated:

BizTalk custom pipeline parsing POP3 PDF attachment error

I have a BizTalk custom pipeline component where I'm parsing a PDF attachment using itexsharp into a custom model. The pipeline is bound to a POP3 receiving port.
In the new created message if I return the attachment stream (outputMessage.GetPart("Body").Data = ms), then this is looking good in the BizTalk administration console. I have been able to save the message from here manually and this was parsed correctly using the same parsing method as in the pipeline.
When parsing the PDF directly in the pipeline, then I'm getting the following error: Rebuild failed: trailer not found.; Original message: xref subsection not found at file pointer 1620729
If I remove the default XMLDisassembler component from pipeline, then the parsing error disappeared, but in the console the message Body is empty, although the AttachmentSizeInBytes=1788
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
return ExtractMessagePartToMessage(pContext, pInMsg);
}
private IBaseMessage ExtractMessagePartToMessage(IPipelineContext pContext, IBaseMessage pInMsg)
{
if (pInMsg.PartCount <= 1)
{
throw new InvalidOperationException("The email had no attachment, apparently.");
}
string partName;
IBaseMessagePart attachmentPart = pInMsg.GetPartByIndex(1, out partName);
Stream attachmentPartStream = attachmentPart.GetOriginalDataStream();
IBaseMessage outputMessage;
outputMessage = pContext.GetMessageFactory().CreateMessage();
outputMessage.AddPart("Body", pContext.GetMessageFactory().CreateMessagePart(), true);
outputMessage.Context = pInMsg.Context;
var ms = new MemoryStream();
attachmentPartStream.CopyTo(ms);
ms.Seek(0L, SeekOrigin.Begin);
Stream orderStream = PdfFormParser.Parse(ms);
outputMessage.GetPart("Body").Data = orderStream;
outputMessage.Context.Write("AttachmentName", "http://schemas.microsoft.com/BizTalk/2003/file-properties", partName);
outputMessage.Context.Write("AttachmentSizeInBytes", "http://schemas.microsoft.com/BizTalk/2003/file-properties", orderStream.Length.ToString());
pContext.ResourceTracker.AddResource(ms);
pContext.ResourceTracker.AddResource(orderStream);
return outputMessage;
}
public static Stream Parse(Stream pdfDocument)
{
using (var reader = new PdfReader(pdfDocument))
{
var outputStream = new MemoryStream();
var pdfForm = ParseInternal(reader);
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(pdfForm.Serialize());
xmlDocument.Save(outputStream);
return outputStream;
}
In pipelines when you read or write a Stream, you have to rewind the stream back to the beginning if something else is going to use it (especially the final message that you expect BizTalk to process).

I want to send additional parameter with message by Smack API client in ejabberd

I am using Ejabberd as XMPP server and creating xmpp client in smack API.I want to send additional parameter with message.
My code is below :
public static void main(String[] args) throws SmackException,IOException,XMPPException {
XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
.setResource("Smack")
.setSecurityMode(SecurityMode.disabled)
.setServiceName("localhost")
.setHost("localhost")
.setPort(Integer.parseInt("5222"))
.build();
AbstractXMPPConnection conn = new XMPPTCPConnection(config);
try {
conn.setPacketReplyTimeout(10000);
SASLAuthentication.unBlacklistSASLMechanism("PLAIN");
SASLAuthentication.blacklistSASLMechanism("SCRAM-SHA-1");
SASLAuthentication.blacklistSASLMechanism("DIGEST-MD5");
//SASLAuthentication.
conn.connect();
conn.login("test1#localhost","123456");
System.out.println("login successfull");
Message message = new Message();
String stanza = "i am vip";
message.setBody(stanza);
stanza+= "<type>.jpg</type>";
ChatManager manager = ChatManager.getInstanceFor(conn);
manager.createChat("vipul#localhost").sendMessage(message);
message.setBody(stanza);
System.out.println("Message Sent");
} catch (Exception e) {
e.printStackTrace();
}
}
By this code i am able to add type in xmpp stanza but i think it is not preferable way.So i need help to send additional parameter with message.
If i get solution this will be appreciated.
Thanks !!
you can add additional parameter like that-
Message message = new Message();
String stanza = "i am vip";
message.setBody(stanza);
message.addBody("customtag","Custom tag value");
message.addBody("customtag1","Custom tag value1");
and you can get it like-
String customtageValue= message.getBody("customtag");
for more detail check this link

Error emailing outgoing sms

Is there anyway to listen for an outbound sms without having to import javax.wireless.messaging?
I'm trying to write an app that listens for an sms sent from the device then emails the message of the sms, but I get the error:
reference to Message is ambiguous, both class
javax.wireless.messaging.Message in javax.wireless.messaging and class
net.rim.blackberry.api.mail.Message in net.rim.blackberry.api.mail
match
I need to import net.rim.blackberry.api.mail.Message in order to sent an email.
Is there a way to get around this as it seems that the two packages are clashing.
My code:
public void notifyIncomingMessage(MessageConnection messageconnection) {}
public void notifyOutgoingMessage(javax.wireless.messaging.Message message) {
try {
String address = message.getAddress();
String msg = null;
if ( message instanceof TextMessage ) {
TextMessage tm = (TextMessage)message;
msg = tm.getPayloadText();
} else if (message instanceof BinaryMessage) {
StringBuffer buf = new StringBuffer();
byte[] data = ((BinaryMessage) message).getPayloadData();
msg = new String(data, "UTF-8");
Store store = Session.getDefaultInstance().getStore();
Folder[] folders = store.list(Folder.SENT);
Folder sentfolder = folders[0];
Message in = new Message(sentfolder);
Address recipients[] = new Address[1];
recipients[0]= new Address("me#us.com", "user");
in.addRecipients(Message.RecipientType.TO, recipients);
in.setSubject("Outgoing sms");
in.setContent("You have just sent an sms to: " + address + "\n" + "Message: " + msg);
in.setPriority(Message.Priority.HIGH);
Transport.send(in);
in.setFlag(Message.Flag.OPENED, true);
Folder folder = in.getFolder();
folder.deleteMessage(in);
}
} catch (IOException me) {
System.out.println(me);
}
}
}
You never should need to import anything in Java. Importing a package is just a shortcut, so that you don't have to fully type out the whole package name. If you have a class named Message that you want to use, and it exists in two packages (both of which you need), then I wouldn't import either of them.
Simply, always refer to each of them by their fully-qualified name:
net.rim.blackberry.api.mail.Message
and
javax.wireless.messaging.Message
It's just a little more typing.

unable to read serialized data as message body in msmq c# 3.0

This is my method to send message to a private Q
using (MessageQueue msgQ = new MessageQueue(MessageQueueName))
{
using (System.Messaging.Message newMessage = new System.Messaging.Message(MessageBody,
new System.Messaging.ActiveXMessageFormatter()))
{
newMessage.Label = MessageLabel;
newMessage.Priority = Priority;
msgQ.Send(newMessage);
}
}
I have an order object which i serialize and send as message body. The serialized object is
<?xml version="1.0"?>
<OrderInfo>
<OrderID>11111</OrderID>
<OrderDetails>
<LineItem>
<ProductDetails>
<Name>qwqwqw</Name>
<Manufacturer>asasas</Manufacturer>
<UPC>12222222222</UPC>
<sku>2132</sku>
<Price>12.21</Price>
</ProductDetails>
<Quantity>1</Quantity>
</LineItem>
</OrderDetails>
</OrderInfo>
This is my method to receive that message in a windows service
void queue_ReceiveCompleted(object sender, ReceiveCompletedEventArgs asyncResult)
{
// Connect to the queue.
MessageQueue mq = (MessageQueue)sender;
// End the asynchronous Receive operation.
Message m = mq.EndReceive(asyncResult.AsyncResult);
m.Formatter = new System.Messaging.ActiveXMessageFormatter()
//Get Filedata from body
OrdrInfo qMessage = (OrdrInfo)XMLUtil.Deserialize(m.Body.ToString(), typeof(OrdrInfo));
}
when I try to look at m.Body in quickwatch this is what it states
m.Body.Message = Cannot find a formatter capable of reading this message.
m.Body.StackTrace = at System.Messaging.Message.get_Body()
Hopefully you're not still stuck on this, but as it came up top of my search when running into the same problem.
As no one had answered it, here is one answer that I've just found else where (thanks TechRepublic). This code assume that "MyType" is a typically basic message that can be read by XML Serialisation - this means it is marked as serializable and all data to be sent/reconstructed is in public get/set properties.
Code is:
MessageQueue msgQ = new MessageQueue(#".\private$\CreateNewEntity");
msgQ.Formatter = new XmlMessageFormatter(new []{typeof(MyType)});
var msg = msgQ.Receive();
msgQ.Close();
return msg.Body as MyType;