Java MimeMessage.saveChanges not calling updateMessageID - java

I am developing an application that needs to send an email via JavaMail with a specific Message ID.
I have extended the Java MimeMessage class to override the updateMessageID method so that I can set the message ID myself. The problem is that when I call the Transport.send(msg) method it is not calling the updateMessageID method. I thought perhaps I needed to call the saveChanges() method prior to calling Transport.send(msg). Even when I explicitly call msg.saveChanges() this does not trigger the updateMessageID method to be called.
What makes this all the more wacky is the fact that when I convert my test application to a JSP and run it, the Transport.send(msg) method DOES call the updateMessageID method.
Both my server and my webserver that I tested on are running jdk1.7.0_71.
Extended MimeMessage Class
package com.my.framework;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class MYMimeMessage extends MimeMessage {
Session session;
private static int id = 0;
private static String messageID = null;
public MyMimeMessage(Session session) {
super(session);
this.session=session;
}
protected void updateMessageID() throws MessagingException {
System.out.println("Calling updateMessageID()");
setHeader("Message-ID", "<" + getUniqueMessageIDValue(session) + ">");
}
/* Added to pass message id in */
public static void setMessageID(String cid)
{
messageID = cid;
}
public static String getUniqueMessageIDValue(Session ssn) {
String suffix = null;
InternetAddress addr = InternetAddress.getLocalAddress(ssn);
if (addr != null)
suffix = addr.getAddress();
else {
suffix = "javamailuser#localhost"; // worst-case default
}
if(messageID == null)
{
messageID = "987654321";
}
StringBuffer s = new StringBuffer();
// Unique string is <messageID>.<id>.<currentTime>.FDDMail.<suffix>
s.append(messageID).append('.').append(getUniqueId()).append('.').
append(System.currentTimeMillis()).append('.').
append("FDDMail.").
append(suffix);
System.out.println("RETURNING THE new ID: " + s.toString()");
return s.toString();
}
private static synchronized int getUniqueId() {
return id++;
}
}
I call this MimeMessageClass from a mail wrapper called SimpleEmail. It is mostly a bunch of get/set functions. All of the meat is in the sendEmail method...
public String sendEmail()
{
String msgText1 = this.getBody();
// Create some properties and get the default Session
Properties props = System.getProperties();
props.put("mail.smtp.host", this.getSmtpClient());
props.put("mail.from", "");
Session session = Session.getDefaultInstance(props, null);
try
{
// Create a message
MyMimeMessage msg = new MyMimeMessage(session);
if (null != sender && sender.length() > 0)
{
msg.setSender(new InternetAddress(sender));
}
if((this.getReply_to() != null) && (this.getReply_to().length() > 0))
{
Address emailReplyTo[] = new Address[1];
emailReplyTo[0] = new InternetAddress(this.getReply_to());
msg.setReplyTo(emailReplyTo);
}
msg.setFrom(new InternetAddress(this.getFrom()));
if(this.to == null || this.to.size() <= 0)
{
return "Error: No To to send";
}
int toIndex = 0;
InternetAddress [] address = new InternetAddress [this.to.size()];
while(this.HasNextTo())
{
address[toIndex] = new InternetAddress(this.nextTo());
toIndex++;
}
msg.setRecipients(Message.RecipientType.TO, address);
if(this.subject == null)
{
this.subject = "<no subject>";
}
msg.setSubject(this.subject);
if(!useTextHeader)
{
//Create and fill the first message part
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setDataHandler(new DataHandler(new HTMLDataSource(msgText1)));
Multipart mp = new MimeMultipart();
mp.addBodyPart(mbp1);
// Create the second message part
MimeBodyPart mbp2;
FileDataSource fds;
String filename;
if(this.attachments != null) {
Set attachmentPathAndNames = this.attachments.keySet();
Iterator attachmentIterator = attachmentPathAndNames.iterator();
while(attachmentIterator.hasNext()) {
String attachmentPathAndName = (String)attachmentIterator.next();
filename = (String)this.attachments.get(attachmentPathAndName);
if(filename == null) {
String[] dirs = attachmentPathAndName.split("\\/");
filename = dirs[dirs.length - 1];
}
mbp2 = new MimeBodyPart();
fds = new FileDataSource(attachmentPathAndName);
mbp2.setDataHandler(new DataHandler(fds));
mbp2.setFileName(filename);
//Create the Multipart and its parts to it
mp.addBodyPart(mbp2);
}
}
//add the Multipart to the message
msg.setContent(mp);
}
else
{
msg.setText(msgText1);
}
//set the Date: header
msg.setSentDate(new Date());
//set the MessageID Header
msg.setMessageID(this.messageID);
//send the message
try
{
Transport.send(msg);
}
catch(Exception e)
{
System.out.println("STOP WE THREW AN ERROR!!!!!!!!!!!!!!!");
}
}
catch (MessagingException mex)
{
mex.printStackTrace();
System.out.println("Error: SimpleEmail.SendEmail() = Caught MessagingException: " + mex.toString());
return "Error: SimpleEmail.SendEmail() = Caught MessagingException: " + mex.toString();
}
return this.SUCESS_MESSAGE;
}
So, when I call from a JSP I can see the two print statements from MyMimeMessage class
<%# page import="com.ifx.framework.SimpleEmail" %>
<%
String toAddr = request.getParameter("emailAddr");
String mid = request.getParameter("customID");
String SMTP_CLIENT = "myserver.mydomain.com";
String body = "Hi " + toAddr + "!<br>Today we are testing to see if the setting messageID to " + mid + " works!";
String sendResult = "No Email Sent";
if(toAddr != null)
{
SimpleEmail se = new SimpleEmail();
se.addTo(toAddr);
se.setSubject("Testing Headers");
se.setSmtpClient(SMTP_CLIENT);
se.setFrom("cms_zippylube#gointranet.com");
se.setBody(body);
se.setMessageID(mid);
sendResult = se.sendEmail();
}
%>
<!DOCTYPE html>
<html>
<head>
<title>
Test Page
</title>
<style>
label {
width: 200px;
display: inline-block;
margin-bottom: 5px;
}
</style>
</head>
<body>
<p style="background-color: #ADD8E6; border: solid 2px #000080;">
<%=sendResult%>
</p>
<form action="#" method="post">
<label for=emailAddr>Email Address:</label><input id="emailAddr" name="emailAddr" type="email"/> <br>
<label for=customValue>Custom Message ID:</label><input id="customID" name="customID" type="text"/> <br>
<input type="submit" value="Submit"/>
</form>
</body>
</html>
In my logs I see:
Calling updateMessage()
RETURNING THE new ID: 8675309.0.1430500125923.FDDMail.javamailuser#localhost
When I check the resulting email, the Message-ID in the header matches what was set.
Here is where my problem is, when I run a standalone version it still sends out the email but doesn't call the updateMessageID method and does not print out the debugging statements.
import com.ifx.framework.SimpleEmail;
public class headerTest
{
public static void main(String args[])
{
String toAddr = args[0];
String mid = args[1];
String SMTP_CLIENT = "myserver.mydomain.com";
String body = "Hi " + toAddr + "!<br>Today we are testing to see if the header message id is retained";
String sendResult = "No Email Sent";
if(toAddr != null)
{
SimpleEmail se = new SimpleEmail();
se.addTo(toAddr);
se.setSubject("Testing Headers");
se.setSmtpClient(SMTP_CLIENT);
se.setFrom("dummy#test.com");
se.setBody(body);
se.setMessageID(mid);
sendResult = se.sendEmail();
}
System.out.println("Done!");
}
}
The only output that I get when I run this is:
Done!
whereas I am expecting
Calling updateMessage()
RETURNING THE new ID: 8675309.0.1430500125923.FDDMail.javamailuser#localhost
Done!
I've got my entire team (including sysadmin) stumped on this issue. Any and All suggestions would be greatly appreciated!

It sounds like you're testing with two different servers so I'm guessing that they're using different versions of JavaMail. What versions are they using? What does the JavaMail debug output show?

Related

How to test an email function in Springboot using MockMvc?

I have this sendmail function that I want to Test in Junit 4 using MockMvc.
I have provided my test case and WiserAssertions.java file I am using to test the function.
When testing the Junit test case I am getting the AssertionError that
java.lang.AssertionError: No message from [demoprojintern#gmail.com] found!
at com.appointment.request.controller.WiserAssertions.lambda$7(WiserAssertions.java:67)
Can someone help me out what am I missing?
sendmail() function
public void sendmail(Request request) throws AddressException, MessagingException, IOException {
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
String email = request.getEmail();
int requestId1 = request.getRequestId();
String requestId = Integer.toString(requestId1);
String name = request.getLegalName();
String cause = request.getCause();
String doa = request.getDateOfAppointment();
String toa = request.getAppointmentTime();
int status = request.getRequestStatus();
String generic = "Hello, " + name + "<br><br>" + "Your request with Request ID: " + requestId + " for " + "the cause of "
+ cause + " on " + doa + " at " + toa + " has been ";
String regards = "<br><br><br>Thanks and Regards,<br>";
Session session = Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("<my-email-id>", "<my-email-id's password");
}
});
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("<my-email-id>", false));
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email));
msg.setSubject("Regarding your Appointment Request");
msg.setContent(" ", "text/html");
msg.setSentDate(new Date());
MimeBodyPart messageBodyPart = new MimeBodyPart();
if (status == 0) {
String messageForPendingRequest = generic + "<strong>RECEIVED</strong>." + regards;
messageBodyPart.setContent(messageForPendingRequest, "text/html");
}
if (status == 1) {
String messageForPendingRequest = generic + "<strong>APPROVED</strong>." + regards;
messageBodyPart.setContent(messageForPendingRequest, "text/html");
}
if (status == 2) {
String messageForPendingRequest = generic + "<strong>SUGGESTED</strong>." + regards;
messageBodyPart.setContent(messageForPendingRequest, "text/html");
}
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
msg.setContent(multipart);
Transport.send(msg);
}
These are the dependencies of my pom.xml for sending the email and testing the mail respectively
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.subethamail</groupId>
<artifactId>subethasmtp</artifactId>
<version>3.1.7</version>
<scope>test</scope>
</dependency>
This is my junit test case
private Wiser wiser;
#Test
public void send() throws Exception {
Request request = new Request(1234, "Richie Rich", "<patient's-email-id>", "Brain", 27, "2019-12-17", "13:00", 0, "", "", "");
String email = request.getEmail();
int requestId1 = request.getRequestId();
String requestId = Integer.toString(requestId1);
String name = request.getLegalName();
String cause = request.getCause();
String doa = request.getDateOfAppointment();
String toa = request.getAppointmentTime();
String generic = "Hello, " + name + "<br><br>" + "Your request with Request ID: "
+ requestId + " for " + "the cause of "
+ cause + " on " + doa + " at " + toa + " has been ";
String regards = "<br><br><br>Thanks and Regards,<br>";
String jsonRequest = objectMapper.writeValueAsString(request);
this.mockMvc.perform(post("/sendemail").content(jsonRequest).contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(status().isOk());
// assert
WiserAssertions.assertReceivedMessage(wiser)
.from("<sender-mail-id>")
.to(email)
.withSubject("Regarding your Appointment Request")
.withContent(generic + "<strong>RECEIVED</strong>." + regards);
}
This is my WiserAssertions.java that I got from a blog
public class WiserAssertions {
private final List<WiserMessage> messages;
private WiserAssertions(List<WiserMessage> messages) {
this.messages = messages;
}
public static WiserAssertions assertReceivedMessage(Wiser wiser) {
return new WiserAssertions(wiser.getMessages());
}
private static Supplier<AssertionError> assertionError(String errorMessage, String... args) {
return () -> new AssertionError(MessageFormat.format(errorMessage, args));
}
public static <T> T unchecked(ThrowingSupplier<T> supplier) {
try {
return supplier.get();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public WiserAssertions from(String from) {
findFirstOrElseThrow(m -> m.getEnvelopeSender().equals(from),
assertionError("No message from [{0}] found!", from));
return this;
}
public WiserAssertions to(String to) {
findFirstOrElseThrow(m -> m.getEnvelopeReceiver().equals(to),
assertionError("No message to [{0}] found!", to));
return this;
}
public WiserAssertions withSubject(String subject) {
Predicate<WiserMessage> predicate = m -> subject.equals(unchecked(getMimeMessage(m)::getSubject));
findFirstOrElseThrow(predicate,
assertionError("No message with subject [{0}] found!", subject));
return this;
}
public WiserAssertions withContent(String content) {
findFirstOrElseThrow(m -> {
ThrowingSupplier<String> contentAsString =
() -> ((String) getMimeMessage(m).getContent()).trim();
return content.equals(unchecked(contentAsString));
}, assertionError("No message with content [{0}] found!", content));
return this;
}
private void findFirstOrElseThrow(Predicate<WiserMessage> predicate, Supplier<AssertionError> exceptionSupplier) {
messages.stream().filter(predicate)
.findFirst().orElseThrow(exceptionSupplier);
}
private MimeMessage getMimeMessage(WiserMessage wiserMessage) {
return unchecked(wiserMessage::getMimeMessage);
}
interface ThrowingSupplier<T> {
T get() throws Throwable;
}
}

Java Mail "From" sender name bad character ÃÃÃÃÃ

I try to send a mail with following code snippet:
message = new MimeMessage(mailSession);
message.setFrom(from);
message.setRecipients(Message.RecipientType.TO, to);
if(cc != null && cc.length > 0){
message.setRecipients(Message.RecipientType.CC, cc);
}
if(bcc != null && bcc.length > 0){
message.setRecipients(Message.RecipientType.BCC, bcc);
}
if(replyTo != null && replyTo.length > 0){
message.setReplyTo(replyTo);
}
message.setSubject(subject, "utf-8");
message.setSentDate(new java.util.Date());
if (headers != null && !headers.isEmpty()) {
for (String headName : headers.keySet()) {
message.addHeader(headName, headers.get(headName));
}
}
if (Utils.isEmpty(bodyText)) {
bodyText = HTMLHelper.html2text(body);
}
message.setContent(this.buildMessageBody(body, bodyText));
transporter = mailSession.getTransport();
transporter.connect();
transporter.sendMessage(message, message.getAllRecipients());
Bellow following additional methods:
private Multipart buildMessageBody(String body, String bodyText) throws MessagingException {
if(attachments == null || attachments.isEmpty()){
return getAlternativeBodyMimeMultipart(body, bodyText);
}
MimeMultipart multipartRoot = new MimeMultipart("mixed");
BodyPart contentBodyPart = buildContentBodyPart(body, bodyText);
multipartRoot.addBodyPart(contentBodyPart);
List<BodyPart> attachmentParts = buildAttachmentParts();
for(BodyPart singleAttachmentPart : attachmentParts){
multipartRoot.addBodyPart(singleAttachmentPart);
}
return multipartRoot;
}
private List<BodyPart> buildAttachmentParts() {
List<BodyPart> attachmentsParts = new ArrayList<BodyPart>();
for (int i = 0; i < attachments.size(); i++) {
BinaryAttachment attach = attachments.get(i);
MimeBodyPart mbp = new MimeBodyPart();
System.setProperty("mail.mime.encodefilename", "true");
try {
mbp.setDataHandler(new DataHandler(attach));
mbp.setFileName(MimeUtility.encodeText(attach.getName()));
attachmentsParts.add(mbp);
} catch (Exception e) {
logger.error("buildBodyWithAttachment",e);
}
}
return attachmentsParts;
}
private BodyPart buildContentBodyPart(String body, String bodyText) throws MessagingException {
MimeMultipart alternativePart = getAlternativeBodyMimeMultipart(body, bodyText);
BodyPart content = new MimeBodyPart();
content.setContent(alternativePart);
return content;
}
For exemple my sender in "from" variable when I call messages.setFrom(from) have following value:
"M. Test ADMINISTRATEURÈÁÍ admin#demo.onmicrosoft.com"
But when I receive my mail in my mailbox, the send have the following name ...
M. Test ADMINISTRATEURÃÃÃ
From: "M. Test ADMINISTRATEUR???" admin#demo.onmicrosoft.com
I think the problem come from the encoding of "from" which create by:
from = new InternetAddress(sender) and sender is "M. Test ADMINISTRATEURÈÁÍ admin#demo.onmicrosoft.com".
How can I solve this?
You will have to specify the charset - UTF-8 in the InternetAddress constructor.
from = new InternetAddress(email, sender, "UTF-8")
The constructor from JavaMail for the above code is as below.
/**
* Construct an InternetAddress given the address and personal name.
* The address is assumed to be a syntactically valid RFC822 address.
*
* #param address the address in RFC822 format
* #param personal the personal name
* #param charset the MIME charset for the name
* #exception UnsupportedEncodingException if the personal name
* can't be encoded in the given charset
*/
public InternetAddress(String address, String personal, String charset)
throws UnsupportedEncodingException {
this.address = address;
setPersonal(personal, charset);
}

Spring Boot embedded HornetQ cluster not forwarding messages

I'm trying to create a static cluster of two Spring Boot applications with embedded HornetQ servers. One application/server will be handling external events and generating messages to be sent to a message queue. The other application/server will be listening on the message queue and process incoming messages. Because the link between the two applications is unreliable, each will use only local/inVM clients to produce/consume messages on their respective server, and relying on the clustering functionality to forward the messages to the queue on the other server in the cluster.
I'm using the HornetQConfigurationCustomizer to customize the embedded HornetQ server, because by default it only comes with an InVMConnectorFactory.
I have created a couple of sample applications that illustrate this setup, throughout this example "ServerSend", refers to the server that will be producing messages, and "ServerReceive" refers to the server that will be consuming messages.
pom.xml for both applications contains:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hornetq</artifactId>
</dependency>
<dependency>
<groupId>org.hornetq</groupId>
<artifactId>hornetq-jms-server</artifactId>
</dependency>
DemoHornetqServerSendApplication:
#SpringBootApplication
#EnableScheduling
public class DemoHornetqServerSendApplication {
#Autowired
private JmsTemplate jmsTemplate;
private #Value("${spring.hornetq.embedded.queues}") String testQueue;
public static void main(String[] args) {
SpringApplication.run(DemoHornetqServerSendApplication.class, args);
}
#Scheduled(fixedRate = 5000)
private void sendMessage() {
String message = "Timestamp from Server: " + System.currentTimeMillis();
System.out.println("Sending message: " + message);
jmsTemplate.convertAndSend(testQueue, message);
}
#Bean
public HornetQConfigurationCustomizer hornetCustomizer() {
return new HornetQConfigurationCustomizer() {
#Override
public void customize(Configuration configuration) {
String serverSendConnectorName = "server-send-connector";
String serverReceiveConnectorName = "server-receive-connector";
Map<String, TransportConfiguration> connectorConf = configuration.getConnectorConfigurations();
Map<String, Object> params = new HashMap<String, Object>();
params.put(TransportConstants.HOST_PROP_NAME, "localhost");
params.put(TransportConstants.PORT_PROP_NAME, "5445");
TransportConfiguration tc = new TransportConfiguration(NettyConnectorFactory.class.getName(), params);
connectorConf.put(serverSendConnectorName, tc);
Set<TransportConfiguration> acceptors = configuration.getAcceptorConfigurations();
tc = new TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
acceptors.add(tc);
params = new HashMap<String, Object>();
params.put(TransportConstants.HOST_PROP_NAME, "localhost");
params.put(TransportConstants.PORT_PROP_NAME, "5446");
tc = new TransportConfiguration(NettyConnectorFactory.class.getName(), params);
connectorConf.put(serverReceiveConnectorName, tc);
List<String> staticConnectors = new ArrayList<String>();
staticConnectors.add(serverReceiveConnectorName);
ClusterConnectionConfiguration conf = new ClusterConnectionConfiguration(
"my-cluster", // name
"jms", // address
serverSendConnectorName, // connector name
500, // retry interval
true, // duplicate detection
true, // forward when no consumers
1, // max hops
1000000, // confirmation window size
staticConnectors,
true // allow direct connections only
);
configuration.getClusterConfigurations().add(conf);
AddressSettings setting = new AddressSettings();
setting.setRedistributionDelay(0);
configuration.getAddressesSettings().put("#", setting);
}
};
}
}
application.properties (ServerSend):
spring.hornetq.mode=embedded
spring.hornetq.embedded.enabled=true
spring.hornetq.embedded.queues=jms.testqueue
spring.hornetq.embedded.cluster-password=password
DemoHornetqServerReceiveApplication:
#SpringBootApplication
#EnableJms
public class DemoHornetqServerReceiveApplication {
#Autowired
private JmsTemplate jmsTemplate;
private #Value("${spring.hornetq.embedded.queues}") String testQueue;
public static void main(String[] args) {
SpringApplication.run(DemoHornetqServerReceiveApplication.class, args);
}
#JmsListener(destination="${spring.hornetq.embedded.queues}")
public void receiveMessage(String message) {
System.out.println("Received message: " + message);
}
#Bean
public HornetQConfigurationCustomizer hornetCustomizer() {
return new HornetQConfigurationCustomizer() {
#Override
public void customize(Configuration configuration) {
String serverSendConnectorName = "server-send-connector";
String serverReceiveConnectorName = "server-receive-connector";
Map<String, TransportConfiguration> connectorConf = configuration.getConnectorConfigurations();
Map<String, Object> params = new HashMap<String, Object>();
params.put(TransportConstants.HOST_PROP_NAME, "localhost");
params.put(TransportConstants.PORT_PROP_NAME, "5446");
TransportConfiguration tc = new TransportConfiguration(NettyConnectorFactory.class.getName(), params);
connectorConf.put(serverReceiveConnectorName, tc);
Set<TransportConfiguration> acceptors = configuration.getAcceptorConfigurations();
tc = new TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
acceptors.add(tc);
params = new HashMap<String, Object>();
params.put(TransportConstants.HOST_PROP_NAME, "localhost");
params.put(TransportConstants.PORT_PROP_NAME, "5445");
tc = new TransportConfiguration(NettyConnectorFactory.class.getName(), params);
connectorConf.put(serverSendConnectorName, tc);
List<String> staticConnectors = new ArrayList<String>();
staticConnectors.add(serverSendConnectorName);
ClusterConnectionConfiguration conf = new ClusterConnectionConfiguration(
"my-cluster", // name
"jms", // address
serverReceiveConnectorName, // connector name
500, // retry interval
true, // duplicate detection
true, // forward when no consumers
1, // max hops
1000000, // confirmation window size
staticConnectors,
true // allow direct connections only
);
configuration.getClusterConfigurations().add(conf);
AddressSettings setting = new AddressSettings();
setting.setRedistributionDelay(0);
configuration.getAddressesSettings().put("#", setting);
}
};
}
}
application.properties (ServerReceive):
spring.hornetq.mode=embedded
spring.hornetq.embedded.enabled=true
spring.hornetq.embedded.queues=jms.testqueue
spring.hornetq.embedded.cluster-password=password
After starting both applications, log output shows this:
ServerSend:
2015-04-09 11:11:58.471 INFO 7536 --- [ main] org.hornetq.core.server : HQ221000: live server is starting with configuration HornetQ Configuration (clustered=true,backup=false,sharedStore=true,journalDirectory=C:\Users\****\AppData\Local\Temp\hornetq-data/journal,bindingsDirectory=data/bindings,largeMessagesDirectory=data/largemessages,pagingDirectory=data/paging)
2015-04-09 11:11:58.501 INFO 7536 --- [ main] org.hornetq.core.server : HQ221045: libaio is not available, switching the configuration into NIO
2015-04-09 11:11:58.595 INFO 7536 --- [ main] org.hornetq.core.server : HQ221043: Adding protocol support CORE
2015-04-09 11:11:58.720 INFO 7536 --- [ main] org.hornetq.core.server : HQ221003: trying to deploy queue jms.queue.jms.testqueue
2015-04-09 11:11:59.568 INFO 7536 --- [ main] org.hornetq.core.server : HQ221020: Started Netty Acceptor version 4.0.13.Final localhost:5445
2015-04-09 11:11:59.593 INFO 7536 --- [ main] org.hornetq.core.server : HQ221007: Server is now live
2015-04-09 11:11:59.593 INFO 7536 --- [ main] org.hornetq.core.server : HQ221001: HornetQ Server version 2.4.5.FINAL (Wild Hornet, 124) [c139929d-d90f-11e4-ba2e-e58abf5d6944]
ServerReceive:
2015-04-09 11:12:04.401 INFO 4528 --- [ main] org.hornetq.core.server : HQ221000: live server is starting with configuration HornetQ Configuration (clustered=true,backup=false,sharedStore=true,journalDirectory=C:\Users\****\AppData\Local\Temp\hornetq-data/journal,bindingsDirectory=data/bindings,largeMessagesDirectory=data/largemessages,pagingDirectory=data/paging)
2015-04-09 11:12:04.410 INFO 4528 --- [ main] org.hornetq.core.server : HQ221045: libaio is not available, switching the configuration into NIO
2015-04-09 11:12:04.520 INFO 4528 --- [ main] org.hornetq.core.server : HQ221043: Adding protocol support CORE
2015-04-09 11:12:04.629 INFO 4528 --- [ main] org.hornetq.core.server : HQ221003: trying to deploy queue jms.queue.jms.testqueue
2015-04-09 11:12:05.545 INFO 4528 --- [ main] org.hornetq.core.server : HQ221020: Started Netty Acceptor version 4.0.13.Final localhost:5446
2015-04-09 11:12:05.578 INFO 4528 --- [ main] org.hornetq.core.server : HQ221007: Server is now live
2015-04-09 11:12:05.578 INFO 4528 --- [ main] org.hornetq.core.server : HQ221001: HornetQ Server version 2.4.5.FINAL (Wild Hornet, 124) [c139929d-d90f-11e4-ba2e-e58abf5d6944]
I see clustered=true in both outputs, and this would show false if I removed the cluster configuration from the HornetQConfigurationCustomizer, so it must have some effect.
Now, ServerSend shows this in the console output:
Sending message: Timestamp from Server: 1428574324910
Sending message: Timestamp from Server: 1428574329899
Sending message: Timestamp from Server: 1428574334904
However, ServerReceive shows nothing.
It appears that the messages are not forwarded from ServerSend to ServerReceive.
I did some more testing, by creating two further Spring Boot applications (ClientSend and ClientReceive), which do not have a HornetQ server embedded and instead connect to a "native" server.
pom.xml for both client applications contains:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hornetq</artifactId>
</dependency>
DemoHornetqClientSendApplication:
#SpringBootApplication
#EnableScheduling
public class DemoHornetqClientSendApplication {
#Autowired
private JmsTemplate jmsTemplate;
private #Value("${queue}") String testQueue;
public static void main(String[] args) {
SpringApplication.run(DemoHornetqClientSendApplication.class, args);
}
#Scheduled(fixedRate = 5000)
private void sendMessage() {
String message = "Timestamp from Client: " + System.currentTimeMillis();
System.out.println("Sending message: " + message);
jmsTemplate.convertAndSend(testQueue, message);
}
}
application.properties (ClientSend):
spring.hornetq.mode=native
spring.hornetq.host=localhost
spring.hornetq.port=5446
queue=jms.testqueue
DemoHornetqClientReceiveApplication:
#SpringBootApplication
#EnableJms
public class DemoHornetqClientReceiveApplication {
#Autowired
private JmsTemplate jmsTemplate;
private #Value("${queue}") String testQueue;
public static void main(String[] args) {
SpringApplication.run(DemoHornetqClientReceiveApplication.class, args);
}
#JmsListener(destination="${queue}")
public void receiveMessage(String message) {
System.out.println("Received message: " + message);
}
}
application.properties (ClientReceive):
spring.hornetq.mode=native
spring.hornetq.host=localhost
spring.hornetq.port=5445
queue=jms.testqueue
Now the console shows this:
ServerReveive:
Received message: Timestamp from Client: 1428574966630
Received message: Timestamp from Client: 1428574971600
Received message: Timestamp from Client: 1428574976595
ClientReceive:
Received message: Timestamp from Server: 1428574969436
Received message: Timestamp from Server: 1428574974438
Received message: Timestamp from Server: 1428574979446
If I have ServerSend running for a while, and then start ClientReceive, it also receives all the messages queued up to that point, so this shows that the messages don't just disappear somewhere, or get consumed from somewhere else.
For completeness sake I've also pointed ClientSend to ServerSend and ClientReceive to ServerReceive, to see if there is some issue with clustering and the InVM clients, but again there was no outout indicating that any message was received in either ClientReceive or ServerReceive.
So it appears that message delivery to/from each of the embedded brokers to directly connected external clients works fine, but no messages are forwarded between brokers in the cluster.
So, after all this, the big question, what's wrong with the setup that messages aren't forwarded within the cluster?
http://docs.jboss.org/hornetq/2.2.5.Final/user-manual/en/html/architecture.html#d0e595
"HornetQ core is designed as a set of simple POJOs so if you have an application that requires messaging functionality internally but you don't want to expose that as a HornetQ server you can directly instantiate and embed HornetQ servers in your own application."
If you are embedding it, you aren't exposing it as a server. Each of your containers has a seperate instance. It is the equivalent of starting up 2 copies of hornet and giving them the same queue name. One writes to that queue on the first instance and the other listens to the queue on the second instance.
If you want to decouple your apps in this way, you need to have a single place that is acting as a server. Probably, you want to cluster. This isn't specific to Hornet, BTW. You'll find this pattern often.
FILTER
package it.unitn.disi.webdev.claudiovigliarolo;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
#WebFilter(filterName = "AuthenticationFilter", urlPatterns = { "/*" })
public class AuthenticationFilter implements Filter {
private ServletContext context;
public void init(FilterConfig fConfig) throws ServletException {
this.context = fConfig.getServletContext();
this.context.log("AuthenticationFilter initialized");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String uri = req.getRequestURI();
HttpSession session = req.getSession(false);
boolean isLoggedIn = session != null && session.getAttribute("username") != null;
if (!isLoggedIn && !uri.endsWith("start.jsp")) {
res.sendRedirect("start.jsp");
} else {
chain.doFilter(request, response);
}
}
public void destroy() {
// close any resources here
}
}<filter-mapping><filter-name>AuthenticationFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
#WebServlet(name = "GetItems", urlPatterns = { "/GetItems" })
public class GetItems extends HttpServlet {
String dbURL = "jdbc:derby://localhost:1527/ExamDerbyDB";
String user = "WEBENGINE";
String password = "WEBENGINE";
Connection conn = null;
#Override
public void init() {
try {
Class.forName("org.apache.derby.jdbc.ClientDriver");
conn = DriverManager.getConnection(dbURL, user, password);
} catch (ClassNotFoundException | SQLException ex) {
ex.printStackTrace();
}
}
#Override
public void destroy() {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException ex) {
System.err.println("Database connection problem: can't close connection");
}
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
StringBuilder ret = new StringBuilder();
ArrayList<String> inserted = getAllItemsFromDB();
String jsonResponse = getListJson(inserted);
response.setContentType("application/json;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
out.println(jsonResponse);
}
}
private ArrayList<String> getAllItemsFromDB() throws ServletException {
ArrayList elements = new ArrayList();
PreparedStatement stm = null;
ResultSet result = null;
try {
String query = "SELECT USERNAME FROM USERS";
stm = conn.prepareStatement(query);
result = stm.executeQuery();
while(result.next()) {
String string = result.getString(1);
elements.add(string);
}
stm.close();
result.close();
} catch (SQLException ex) {
System.err.println("Database connection problem");
} finally {
try {
if(stm != null) stm.close();
if(result != null) result.close();
} catch (SQLException ex) {
System.err.println("Database connection problem: can't close statement/result");
}
return elements;
}
public String getListJson(ArrayList<String> list) {
if (list.size() == 0)
return null;
StringBuilder ret = new StringBuilder("[");
String prefix = "";
for (int i = 0; i < list.size(); i++) {
StringBuilder sb = new StringBuilder();
ret.append(prefix);
prefix = ",";
ret.append(sb.append("{\"message\":\"").append(list.get(i)).append("\"}").toString());
}
ret.append("]");
return ret.toString();
}
}
class.java
public class MessageList {
protected final LinkedList<Message> list;
public MessageList() {
this.list = new LinkedList<>();
}
public void addMessage(Message m) {
this.list.add(m);
}
public void deleteMessage(String message_id) {
for (Message a : list) {
if (a.message_id.equals(message_id)) {
list.remove(a);
}
}
}
public Message getMessage(String message_id) {
for (Message a : list) {
if (a.message_id.equals(message_id)) {
return a;
}
}
return null;
}
public void addLike(String message_id) {
for (Message a : list) {
if (a.message_id.equals(message_id)) {
a.isLiked++;
}
}
}
StringBuilder ret = new StringBuilder("[");
String prefix = "";for(
int i = 0;i<list.size();i++)
{
Message m = list.get(i);
ret.append(prefix);
prefix = ",";
ret.append(m.toJson());
}ret.append("]");
return ret.toString();
}
public String getListJson()
{
if(list.size() == 0)
{
return null;
}
StringBuilder ret = new StringBuilder("[");
String prefix = "";
for(int i=0; i<list.size(); i++) {
StringBuilder sb = new StringBuilder();
ret.append(prefix);
prefix = ",";
ret.append(sb.append("{\"message\":\"").append(list.get(i)).append("\"}").toString());
}
ret.append("]");
return ret.toString();
}
}
form
<!DOCTYPE html>
<html lang="en">
<body>
<script>
function validateForm(form) {
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
var error = document.getElementById("error");
error.innerHTML = "";
if (username === "" || password == "") {
form.reset();
error.innerHTML = "password / username empty";
return false;
}
return true;
}
</script>
<div class="container" style="width: 500px; float: left">
<h2 class="text-center">Welcome to the App</h2>
<form
id="registerForm"
method="POST"
onsubmit="return validateForm(this)"
action="Registration"
>
<div class="form-group">
<label for="username">Username:</label>
<input
type="text"
class="form-control"
id="username"
placeholder="Enter email"
name="username"
/>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input
type="password"
class="form-control"
id="password"
placeholder="Enter password"
name="password"
/>
</div>
<div class="form-group form-check"></div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<div id="error" class="alert" role="alert"></div>
</div>
</body>
</html>
general
//servelet context
ServletContext application=getServletContext();
application.setAttribute("messages", messages);
//SESSION
HttpSession session = request.getSession();
String name = (String) request.getParameter("username");
session.setAttribute("username", name);
//random id java
String uniqueID = UUID.randomUUID().toString();
//package
it.unitn.disi.webdev.claudiovigliarolo
//project name
VIGLIAROLO_C_202314
//get contextpath
String contextPath = request.getContextPath();
System.out.println("Context Path = " + contextPath);
response.sendRedirect(contextPath + "/main.html");
//BOOTstrap
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
//redirect to other page
window.location.replace("http://stackoverflow.com");
//CONTENT type
response.setContentType("application/json;charset=UTF-8");
response.setContentType("text/html;charset=UTF-8");
//zuccherino
protected final LinkedList<Message> list;
public MessageList() {
this.list = new LinkedList<>();
}
<!DOCTYPE html>
<html lang="en">
<body>
<script>
function validateForm(form) {
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
var error = document.getElementById("error");
error.innerHTML = "";
if(username === "" || password == "") {
form.reset();
error.innerHTML = "password / username empty";
return false;
}
return true;
}
</script>
<div class="container " style="width:500px; float: left;">
<h2 class="text-center">Welcome to the App</h2>
<form id="registerForm" method="POST" onsubmit="return validateForm(this)" action="Registration">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" class="form-control" id="username" placeholder="Enter email" name="username">
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" class="form-control" id="password" placeholder="Enter password" name="password">
</div>
<div class="form-group form-check">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<div id="error" class="alert" role="alert">
</div>
</div>
</body>
</html>
//change styles
const val = keywords.some(k=>item.message.includes(k));
const color = val ? "#FFFF00;" : "transparent;";
document.getElementById("data").innerHTML +=
"<div style=' margin-top:50px;flexdirection: row; display:flex; width:500px; background:" + color + "; justify-content: row; '>" +
item.message +
"</div>";
//setimeout
function refresh() {
// make Ajax call here, inside the callback call:
setTimeout(refresh, 5000);
// ...
}
// initial call, or just call refresh directly
setTimeout(refresh, 5000);
//template strings
`string text`
getclaudio postclaudio
<script>
function onSendData() {
var title = document.getElementById("username").value;
var description = document.getElementById("password").value;
console.log(title, description);
var http = new XMLHttpRequest();
var url = "Registration";
var params = "password=" + description + "&username=" + title;
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.onreadystatechange = function () {
//Call a function when the state changes.
if (http.readyState == 4 && http.status == 200) {
console.log("res", http.responseText);
}
};
http.send(params);
}
</script>
------GET---------------
//loadData noparam
<script>
loadData();
function loadData() {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "GetProducts", true);
xhttp.responseType = "json";
xhttp.onreadystatechange = function () {
var done = 4,
ok = 200;
if (this.readyState === done && this.status === ok) {
my_JSON_object = this.response;
console.log("response", my_JSON_object);
document.getElementById("data").innerHTML = "";
my_JSON_object && my_JSON_object.forEach((item) => {
console.log("item", item.message);
document.getElementById("data").innerHTML +=
" <div class='card' style='width: 300px; margin-top:50px;'>" +
"<div class='card-body'>" +
" <h4 class='card-title'>" + item.name + "</h4>" +
"<p class='card-text'>" + item.description + "</p>" +
" <p class='card-text'>Price: " + item.price + " $</p>" +
" <a href='detail.html?name=" + item.name + "' class='card-link' >View details</a>" +
" </div> </div>";
});
}
};
xhttp.send();
}
</script>
<div id="data"></div>
//loadData withparam
<script>
function getData() {
const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get('id');
const id2 = urlParams.get('id2');
console.log(id)
var url = "GetItems";
let param1 = id;
let param2 = id2;
var params = "param1=" + param1 + "&param2=" + param2;
var http = new XMLHttpRequest();
http.open("GET", url + "?" + params, true);
http.responseType = "json";
http.onreadystatechange = function () {
var done = 4,
ok = 200;
if (this.readyState === done && this.status === ok) {
my_JSON_object = this.response;
console.log("response", my_JSON_object);
document.getElementById("data").innerHTML = "";
my_JSON_object && my_JSON_object.forEach((item) => {
console.log("item", item.message);
document.getElementById("data").innerHTML +=
"<div style=' margin-top:50px;flexdirection: row; display:flex; width:500px; justify-content: row; '>" +
item.message +
"</div>";
});
}
};
http.send(null);
}
</script>
<div id="data"></div>
<div class="card" style="margin-top: 50px;">
<div class="card-body">Content</div>
</div>
//render multiple parameters
onclick="showData('${item.name}', '${item.price}', '${item.punteggio}', '${item.extra}' )"
JSON servelet claudio
RETURN JSON
//create simple json response
response.setContentType("application/json;charset=UTF-8");
StringBuilder ret = new StringBuilder();
ret.append("{\"ready\":\"").append("false").append("\"}");
try (PrintWriter out = response.getWriter()) {
out.println(ret.toString());
}
JSON LIST CLASS
public String toJSON() {
StringBuilder ret = new StringBuilder("[");
String prefix = "";
for(int i=0; i<list.size(); i++) {
Message m = list.get(i);
ret.append(prefix);
prefix = ",";
ret.append(m.toJson());
}
ret.append("]");
System.err.println("priting tojson"+ ret.toString());
return ret.toString();
}
JSON ITEM
public String toJson() {
StringBuilder ret = new StringBuilder();
ret.append("{\"id\":\"").append(this.id).append("\",");
ret.append("\"nome\":\"").append(this.nome).append("\",");
ret.append("\"imgName\":\"").append(this.imgName).append("\"}");
return ret.toString();
}
STRING LIST
public String wordsToJSON(ArrayList<String> list) {
System.err.println("lunghezza" + list.size());
if (list.size() == 0) {
return null;
}
StringBuilder ret = new StringBuilder("[");
String prefix = "";
for (int i = 0; i < list.size(); i++) {
StringBuilder sb = new StringBuilder();
ret.append(prefix);
prefix = ",";
ret.append(sb.append("{\"message\":\"").append(list.get(i)).append("\"}").toString());
}
ret.append("]");
System.err.println("jjj" + ret.toString());
return ret.toString();
}
}
JSON RESPONSE OK
ServletContext application=getServletContext();
MappaDiCoppie mappaDiCoppie = (MappaDiCoppie) application.getAttribute("mappaDiCoppie");
HttpSession session= request.getSession();
String username = (String) session.getAttribute("username");
StringBuilder ret = new StringBuilder();
if(mappaDiCoppie != null && username != null)
{
if(mappaDiCoppie.exists(username))
//ok
ret.append("{\"ready\":\"").append("true").append("\"}");
else
//no wait
ret.append("{\"ready\":\"").append("false").append("\"}")
try (PrintWriter out = response.getWriter()) {
out.println(ret.toString());
}
}
```
stylesheet
<link rel="stylesheet" href="./styles/styles.css">
<script type="text/javascript" src="./js/script.js"></script>
matrix html
const N = 9;
const container = document.getElementById("container");
function makeRows(rows, cols) {
container.style.setProperty('--grid-rows', rows);
container.style.setProperty('--grid-cols', cols);
for (c = 0; c < (cols); c++) {
for (r = 0; r < rows; r++) {
const myid = JSON.stringify({x: r, y: c});
let cell = document.createElement("div");
var textnode = document.createElement("span");
textnode.setAttribute("id", myid);
cell.appendChild(textnode);
cell.onclick = function (event) {
showVal(myid, r, c);
}
//cell.innerText = (c + 1);
container.appendChild(cell).className = "grid-item";
container.appendChild(cell).style = "border-color: red";
container.appendChild(cell).style = "border-width: 4px";
}
;
}
}
//styles
.myinput{
width: 50px;
margin-right: 20px;
}
#container {
display: grid;
grid-gap: .5em;
grid-template-rows: repeat(var(--grid-rows), 1fr);
grid-template-columns: repeat(var(--grid-cols), 1fr);
width: 100px;
}
.grid-item {
border: 1px solid #ddd;
text-align: center;
width: 50px;
height: 50px;
border-width: 2px;
border-color: green;
}
grid java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package utils;
import java.util.ArrayList;
import java.util.Random;
/**
*
* #author claud
*/
public class Grid {
int N;
Cell[][] matrix;
public Grid(int N) {
this.N = N;
this.matrix = new Cell[N][N];
}
private int getRandom() {
Random rn = new Random();
int range = 0 - 0 + 1;
int randomNum = rn.nextInt(N) + 0;
return randomNum;
}
public int getValue(int x, int y) {
if (x < N && y < N) {
return this.matrix[x][y].value;
} else {
return -2;
}
}
public void generate() {
System.err.println("ffffffffffffggg");
//fai il ciclo completo
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
this.matrix[i][j] = new Cell(i, j, 0);//aggiungi bombe con random altrimenti valore 0
}
}
}
public void print() {
System.err.println("printiiiiiiiiiiiing START");
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
System.err.println(this.matrix[i][j].value);
}
}
}
}

how to read mails with attached from MS exchange with java mail and EWS

I have a problem when I use javamail4ews-0.0.8 for reading mails from MS exchange server 2010
I connect successful
and I read every mail that I have but when I try to see the attachment I only can't see nothing.
I look the contentType his valor is "text/plain" and when I read the getContent().getClass() is String. if I see the information that contain the text/plain this mentioned that is a MimeMultipart beacause have the leyend MIME-Version: 1.0
I look my mail and contain a PDF and XML
I don't know why the program return me a contentType="text/plain" and getContent().getClass()=String
I need one Multipart or MimeMultipart but I don't know how to convert that.
I add my code ....
Thanks guys.
import javax.mail.MessagingException;
import javax.mail.Store;
public class Test {
public static void main(String[] args){
StoreMail test = new StoreMail(
"user",
"password",
"https://<exchangeServer>/ews/exchange.asmx",
"ewsstore",
"C:\\");
//public StoreMail( String userMail, String passMail, String host, String protocolo, String directorio) {
try {
test.readEmails(1);
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
and
public class StoreMail {
public StoreMail( String userMail, String passMail, String host, String protocolo, String directorio) {
....
}
public void readEmails( int cantidad ) throws MessagingException {
Properties props = System.getProperties();
props.setProperty("directorio","C:\\BASURA\\\\" );
props.setProperty("dircliente","C:\\BASURA\\\\" );
Session session = Session.getInstance(props, null);
System.out.println( host+" "+userMail+" "+passMail );
Store store = session.getStore(protocolo);
store.connect(host, userMail, passMail);
Folder currFolder = store.getDefaultFolder();
Message[] messages = currFolder.getMessages();
for (Message message : messages) {
try {
Object body = message.getContent();
System.out.println("BODY:::::"+body.getClass()); // is class java.lang.String
if (body instanceof Multipart) { // or instanceof MimeMultipart
System.out.println( " MimeMultipart" );
procMultipart((Multipart) body)
} else {
System.out.println(" other:");
procPart(message);
}
}catch (Throwable thrbl) {
thrbl.printStackTrace();
}
}
}
public void procPart( Part p ) {
try {
String contentType = p.getContentType();
if ( contentType != null ){
//if (p.isMimeType("multipart/alternative")) {
//System.out.println("is multipart/alternative");
//}else{
if ( contentType.toLowerCase().startsWith( "multipart/" ) ) {
procMultipart(( Multipart ) p)
}else{
if(contentType.toLowerCase().startsWith( "text/plain" )){
//I don't know what to do because is a Mime Multipart... and I need to read it
// I need transform the attached to PDF and XML and Save it
}else{
System.out.println("other contentType"+contentType);
String nomfich = p.getFileName();
if (nomfich != null) {
if( nomfich.toLowerCase().endsWith( ".xml" ) ) {
System.out.println(" XML octet-stream nomfich: " + nomfich);
saveArchXML( p.getInputStream() );
} else if( nomfich.toLowerCase().endsWith( ".pdf" ) ) {
saveArchPDF( p.getInputStream(),nomfich.toLowerCase() );
} else if( nomfich.toLowerCase().endsWith( ".zip" ) ) {
saveArchZIP( p.getInputStream(),nomfich.toLowerCase() );
}else{
}
}
}
}
//}
}
} catch ( Exception ex ) {
ex.printStackTrace();
}
}
public void procMultipart(Multipart mp) throws MessagingException {
for (int i = 0; i < mp.getCount(); i++) {
logger.info(" procMultipart :" + i);
Part p = mp.getBodyPart(i);
procPart(p);
}
}
}
You need to learn a lot more about internet email and MIME messages. Start with these JavaMail FAQ entries:
Where can I learn the basics about Internet email that I'll need to know to program JavaMail effectively?
Where can I find some example programs that show how to use JavaMail?
How do I find the main message body in a message that has attachments?
In particular, see the msgshow.java demo program available from the link above.
With JWebServices for Exchange it looks easy
Find messages with attachments

Javamail reply removing or modifying message-id header

I want to modify or remove the "Message-ID" header when replying to an email with Javamail. After some research I found out I need to create a custom class that extends MimeMessage. Here is the class that I have created.
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
class MyMessage extends MimeMessage
{
public MyMessage(Session session)
{
super(session);
}
#Override
protected void updateMessageID() throws MessagingException {
removeHeader("Message-Id");
}
}
The code below is related to fetching the messages
public List<EmailSenderInfo> checkEmail() throws Exception
{
String host = "HOST";
String username = "MYUSERNAME";
String password = "MYPASS";
List<EmailSenderInfo> emailSenderList = new ArrayList<EmailSenderInfo>();
Properties properties = System.getProperties();
properties.setProperty("mail.store.protocol", "imaps");
Session session = Session.getDefaultInstance(properties);
Store store = session.getStore("imaps");
store.connect(host, username, password);
/*
* Folder[] f = store.getDefaultFolder().list(); for (Folder fd : f)
* System.out.println(">> " + fd.getName());
*/
Folder folder = store.getFolder("INBOX");
if (!folder.exists())
{
System.out.println("No INBOX...");
System.exit(0);
}
folder.open(Folder.READ_WRITE);
Message[] msg = folder.getMessages();
if (msg.length < 1)
{
System.out.println("No new messages!");
throw new Exception("No new messages!");
}
for (int i = 0; i < msg.length; i++)
{
if (!msg[i].isSet(Flag.SEEN))
{
EmailSenderInfo emailSenderInfo = new EmailSenderInfo();
emailSenderInfo.message = msg[i];
System.out.println("------------ Message " + (i + 1) + " ------------");
// String from = InternetAddress.toString(msg[i].getFrom());
Address[] fromArray = msg[i].getFrom();
InternetAddress fromInternetAddress = (InternetAddress) fromArray[0];
String from = fromInternetAddress.getAddress();
String fromName = fromInternetAddress.getPersonal();
if (fromName != null)
{
emailSenderInfo.fromName = fromName;
}
if (from != null)
{
// System.out.println("From: " + from);
emailSenderInfo.from = from;
}
// String replyTo = InternetAddress.toString(msg[i].getReplyTo());
Address[] replyToArray = msg[i].getFrom();
InternetAddress ReplyToInternetAddress = (InternetAddress) replyToArray[0];
String replyTo = ReplyToInternetAddress.getAddress();
String replyToName = ReplyToInternetAddress.getPersonal();
if (replyTo != null)
{
// System.out.println("Reply-to: " + replyTo);
emailSenderInfo.replyTo = replyTo;
}
if (replyToName != null)
{
// System.out.println("Reply-to: " + replyTo);
emailSenderInfo.replyToName = replyToName;
}
String to = InternetAddress.toString(msg[i].getRecipients(Message.RecipientType.TO));
if (to != null)
{
// System.out.println("To: " + to);
emailSenderInfo.to = to;
}
String subject = msg[i].getSubject();
if (subject != null)
{
// System.out.println("Subject: " + subject);
emailSenderInfo.subject = subject;
}
Date sentDate = msg[i].getSentDate();
if (sentDate != null)
{
System.out.println("Sent: " + sentDate);
emailSenderInfo.sentDate = sentDate;
}
String bodyHtml = "";
// get content
Multipart multipart = (Multipart) msg[i].getContent();
for (int x = 0; x < multipart.getCount(); x++)
{
BodyPart bodyPart = multipart.getBodyPart(x);
String disposition = bodyPart.getDisposition();
if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()))
{
// dealing with attachments only
System.out.println("Mail has some attachment : ");
DataHandler handler = bodyPart.getDataHandler();
System.out.println("file name : " + handler.getName());
System.out.println("ddddd: " + bodyPart.getContent().toString());
}
else
{
String classType = bodyPart.getContent().getClass().toString();
if (classType.contains("java.lang.String"))
{
bodyHtml = bodyPart.getContent().toString();
}
else if (classType.contains("javax.mail.internet.MimeMultipart"))
{
MimeMultipart bodyContent = (MimeMultipart) bodyPart.getContent();
for (int b = 0; b < bodyContent.getCount(); b++)
{
IMAPBodyPart imapBody = (IMAPBodyPart) bodyContent.getBodyPart(b);
System.out.println("1: " + imapBody.getContent());
bodyHtml = imapBody.getContent().toString();
// System.out.println("2: " + bodyContent.getBodyPart(b));
// System.out.println("3: " + bodyPart.getContent().toString());
}
}
}
emailSenderInfo.bodyHtml = bodyHtml;
}
MyMessage reply = (MyMessage) msg[i].reply(false);
emailSenderInfo.reply = reply;
// reply.setFrom(msg[i].getFrom()[0]);
MimeMessage orig = (MimeMessage) msg[i];
StringBuffer buffer = new StringBuffer("Thanks\n\n");
if (orig.isMimeType("text/plain"))
{
String content = (String) orig.getContent();
StringReader contentReader = new StringReader(content);
BufferedReader br = new BufferedReader(contentReader);
String contentLine;
while ((contentLine = br.readLine()) != null)
{
buffer.append("> ");
buffer.append(contentLine);
buffer.append("\r\n");
}
}
// Set the reply content
// reply.setText(buffer.toString());
// emailSenderInfo.reply = reply;
emailSenderList.add(emailSenderInfo);
// System.out.println();
}// end if unread
}
folder.close(true);
store.close();
return emailSenderList;
}
I have two methods in my program. One of them checks mail and another one which replies to emails.
Message reply = msg[i].reply(false);
"reply" gets passed to this method along with other parameters.
public void sendReply(String from, String replyTo, Message reply, String messageReply, Boolean attachment) throws Exception
{
String host = "MYHOST";
String username = "MYUSERNAME";
String pass = "MYPASSWORD";
Properties props = System.getProperties();
props.put("mail.smtp.starttls.enable", "true"); // added this line
props.put("mail.smtp.host", host);
props.put("mail.smtp.user", username);
props.put("mail.smtp.password", pass);
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props);
MimeMessage mimeReply = (MimeMessage) reply;
mimeReply.setFrom((Address) InternetAddress.parse(from)[0]);
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(messageReply, "text/html");
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
if (attachment)
{
messageBodyPart = new MimeBodyPart();
String filename = "test.jpg";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
}
mimeReply.setContent(multipart);
Transport transport = session.getTransport("smtp");
transport.connect(host, username, pass);
transport.sendMessage(mimeReply, InternetAddress.parse(replyTo));
transport.close();
System.out.println("Message Sent!");
}
I have to use the MyMessage class in order to remove the "Message-ID" header. I have tried the following
MyMessage mimeReply = (MyMessage) reply;
But I get the following error in runtime
java.lang.ClassCastException: javax.mail.internet.MimeMessage cannot be cast to javamailer.MyMessage
How can use "MyMessage" class so I can remove the "Message-ID" header with the reply message?
You can try the following:
When replying to an email:
When you create a message create, right now it should be like:
MimeMessage msg = new MimeMessage(session);
change it to,
MyMessage msg = new MyMessage(session);
When checking email you don't need to remove the header as that message is already in the mailbox, what I think you need to do is when replying to a mail at that instance for the name mail instantiate like :
MyMessage msg = new MyMessage(session);
msg.updateMessageID();
Since you are using reference to existing message:
You can do something like:
Create a new constructor:
public MyMessage (MimeMessage message) {
super(message);
}
When replying:
MyMessage mimeReply = new MyMessage(reply);
mimeReply.updateMessageID();
Then send the mimeReply NOT reply.

Categories