ok so I use .getcontent and receive javax.mail.internet.MimeMultipart#fd13b5 etc.
I know i need something like this in my code but i dont know what exactly is needed.
if (p.isMimeType("text/plain")) {
pr("This is plain text");
pr("---------------------------");
if (!showStructure && !saveAttachments)
System.out.println((String)p.getContent());
} else if (p.isMimeType("multipart/*")) {
pr("This is a Multipart");
pr("---------------------------");
Multipart mp = (Multipart)p.getContent();
level++;
int count = mp.getCount();
for (int i = 0; i < count; i++)
dumpPart(mp.getBodyPart(i));
level--;
} else if (p.isMimeType("message/rfc822")) {
pr("This is a Nested Message");
pr("---------------------------");
level++;
dumpPart((Part)p.getContent());
level--;
at the moment i am trying to put all the information in to astring which is then shown up on a GUI at the moment i have it all working fine bar the body content which is showing as.
javax.mail.internet.MimeMultipart#fd13b5. any help would be much appreciated as im quite stuck.
package EmailTable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class Email implements ActionListener
{
private mail mail;
private List mails;
private String password;
private String user;
private String getText;
private boolean textIsHtml = false;
public Email(List mails,String password,String user) throws MessagingException, IOException {
password = "password";
user = "user";
this.mails = mails;
String host = "10..10.10.10";
Properties properties = System.getProperties();
Session session = Session.getDefaultInstance(properties);
Store store = session.getStore("pop3");
store.connect(host, user, password);
Folder folder = store.getFolder("inbox");
folder.open(Folder.READ_ONLY);
Message[] messages = folder.getMessages();
int length = messages.length-1;
for (int i = length; i > length-30; i--) {
mail = new mail();
mail.setEmail(messages[i].getFrom()[0]);
String to = InternetAddress.toString(
messages[i].getRecipients(Message.RecipientType.TO));
if (to != null) {
mail.setEmail2(to);
}
mail.setSubject(messages[i].getSubject());
mail.setDate(messages[i].getSentDate());
mail.setMessage(messages[i]);
mail.setContent(((MimeMessage)messages[i]).getContent());
Email.this.mails.add(mail);
}
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
Yes, you have to iterate through each BodyPart to know it's type and then get the content accordingly. Here's what I used to get the content of a message. But still I am not able to get the right content for some messages.
Edited
Works better after implementing the code suggested by Bill.
Object msgContent = messages[i].getContent();
String content = "";
/* Check if content is pure text/html or in parts */
if (msgContent instanceof Multipart) {
Multipart multipart = (Multipart) msgContent;
Log.e("BodyPart", "MultiPartCount: "+multipart.getCount());
for (int j = 0; j < multipart.getCount(); j++) {
BodyPart bodyPart = multipart.getBodyPart(j);
String disposition = bodyPart.getDisposition();
if (disposition != null && (disposition.equalsIgnoreCase("ATTACHMENT"))) {
System.out.println("Mail have some attachment");
DataHandler handler = bodyPart.getDataHandler();
System.out.println("file name : " + handler.getName());
}
else {
content = getText(bodyPart); // the changed code
}
}
}
else
content= messages[i].getContent().toString();
This solution worked much better for me. I merely wanted to log my email message for development/testing purposes. Use the MimeMessage.writeTo(OutputStream) method.
void logMimeMessage(MimeMessage msg) throws MessagingException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
msg.writeTo(out);
} catch (IOException e) {
logger.catching(new MyException("Cannot log MimeMessage",e));
}
logger.error(out.toString());
}
Thanks to the comment by #zzzzz above, who linked to this answer JavaMail - Parsing email content, can't seem to get it to work! (Message.getContent())
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have write a readFromSharedInbox() method. When I am checking the code with sonarLint i am getting this error "Refractor this method to reduce its cognitive complexity". So i want to break this method in two parts. But i am not able to do so.I am trying to create a method to read the mail from inbox.
My Code look like this
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.ContentType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.mail.search.ComparisonTerm;
import javax.mail.search.FlagTerm;
import javax.mail.search.ReceivedDateTerm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;
#Service
public class MailServiceImpl implements MailService {
#Value("${mail.host}")
private String host;
#Value("${mail.id}")
private String mailBoxId;
#Value("${mail.password}")
private String password;
#Value("${mail.protocol}")
private String protocol;
#Value("${mail.socketfactory}")
private String socketfactory;
#Value("${mail.fallback}")
private String fallback;
#Value("${mail.port}")
private String port;
#Value("${mail.savepath}")
private String savepath;
#Value("${submission.fields}")
private String fields;
#Value("${mail.endidentifier}")
private String mailEndIdentifier;
#Autowired
private EmailRequestRepository emailRequestRepository;
#Autowired
private CoreWorkflowService coreWorkflowService;
public void readFromSharedInbox() {
Properties props = new Properties();
props.setProperty("mail.store.protocol", protocol);
props.setProperty("mail.imaps.socketFactory.class", socketfactory);
props.setProperty("mail.imaps.socketFactory.fallback", fallback);
props.setProperty("mail.imaps.port", port);
props.setProperty("mail.imaps.socketFactory.port", port);
Session session = Session.getDefaultInstance(props, null);
try {
Store store = session.getStore(protocol);
store.connect(host, mailBoxId, password);
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
ReceivedDateTerm receivedDateTerm = new ReceivedDateTerm(ComparisonTerm.EQ, new Date());
FlagTerm seenTerm = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
Message[] todaysMessages = inbox.search(receivedDateTerm);
Message[] foundMessages = inbox.search(seenTerm, todaysMessages);
List<EmailRequest> emailRequestList = new ArrayList<>();
for (int i = 0; i < foundMessages.length; i++) {
Message message = foundMessages[i];
String subject = message.getSubject();
String content = message.getContent().toString();
String contentType = message.getContentType();
Address[] froms = message.getFrom();
String sender = froms == null ? null : ((InternetAddress) froms[0]).getAddress();
Date recieveDate = message.getReceivedDate();
// store attachment file name, separated by comma
StringBuilder attachFiles=new StringBuilder();
if (contentType.contains("multipart")) {
// content may contain attachments
MimeMultipart multiPart = (MimeMultipart) message.getContent();
content = getTextFromMimeMultipart(multiPart);
int numberOfParts = multiPart.getCount();
for (int partCount = 0; partCount < numberOfParts; partCount++) {
MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(partCount);
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
// this part is attachment
String fileName = part.getFileName();
if (attachFiles.length() > 0) {
attachFiles.append(",");
attachFiles.append(fileName);
} else {
attachFiles.append(fileName);
}
System.out.println(fileName);
}
}
message.writeTo(new FileOutputStream(new File(savepath + sanitizeFileName(subject) + ".eml")));
}
System.out.println("Content type: " + contentType);
EmailRequest emailRequest = EmailRequest.builder().emailRecieveDate(recieveDate).subjectEmail(subject)
.emailContent(content).fromEmail(sender).toEmail(mailBoxId).isMailProcessed(false).build();
emailRequestList.add(emailRequest);
}
inbox.close(false);
store.close();
System.out.println("reading done!");
emailRequestRepository.saveAll(emailRequestList);
System.out.println("Email data saved successfully in db table");
} catch (Exception e) {
e.printStackTrace();
}
}
private String sanitizeFileName(String subject) {
return subject.replaceAll("[:\\\\/*?|<>]", "_");
}
private String getTextFromMimeMultipart(MimeMultipart mimeMultipart) throws IOException, MessagingException {
int count = mimeMultipart.getCount();
if (count == 0)
throw new MessagingException("Multipart with no body parts not supported.");
boolean multipartAlt = new ContentType(mimeMultipart.getContentType()).match("multipart/alternative");
if (multipartAlt)
// alternatives appear in an order of increasing
// faithfulness to the original content. Customize as req'd.
return getTextFromBodyPart(mimeMultipart.getBodyPart(count - 1));
StringBuilder result = new StringBuilder();
for (int i = 0; i < count; i++) {
BodyPart bodyPart = mimeMultipart.getBodyPart(i);
result.append(getTextFromBodyPart(bodyPart));
}
return result.toString();
}
private String getTextFromBodyPart(BodyPart bodyPart) throws IOException, MessagingException {
String result = "";
if (bodyPart.isMimeType("text/plain")) {
result = (String) bodyPart.getContent();
} else if (bodyPart.isMimeType("text/html")) {
result = (String) bodyPart.getContent();
} else if (bodyPart.getContent() instanceof MimeMultipart) {
result = getTextFromMimeMultipart((MimeMultipart) bodyPart.getContent());
}
return result;
}
#Override
public void readMailDetailsFromDb() {
EmailRequest email = new EmailRequest();
email.setIsMailProcessed(false);
Example<EmailRequest> whereClause = Example.of(email);
List<EmailRequest> findAll = emailRequestRepository.findAll(whereClause);
Map<String, Object> processVariables = null;
for (EmailRequest emaeil : findAll) {
System.out.println(emaeil.getSubjectEmail() + " : " + emaeil.getEmailId());
processVariables = EmailParserUtil.parse(fields, emaeil.getEmailContent(), mailEndIdentifier);
// workflow service
try {
Workflow startWorkflow = coreWorkflowService.startWorkflow(Constants.SUBMISSION_PROCESS_ID, Constants.MAIL, processVariables);
startWorkflow.toString();
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
// update mail
emaeil.setMailProcessedOn(LocalDateTime.now() ) ;
emaeil.setIsMailProcessed(true) ;
emailRequestRepository.save(emaeil) ;
}
}
}
This is MailService Class
import java.lang.reflect.InvocationTargetException;
public interface MailService {
public void readFromSharedInbox();
public void readMailDetailsFromDb() throws IllegalAccessException, InvocationTargetException;
}
You can use your IDE for things like that.
You select a part of your code, right click on it and refactor it by extracting the code in a new private method.
For exemple, you can do this on the "for" statement.
Or the "if (contentType.contains("multipart"))" part with a manageMultipart method.
I'm using snmp4j 3.4.2 inside my java application (full code below)
I'm trying to execute a snmpget with snmpv3, security DES and auth MD5 and custom OID (python script, which is executed by snmp's extend funtionality). To create better understanding I used SnmpConstants.sysUpTime in the example below.
The SNMP resource has this user configured:
defSecurityName demo
defSecurityLevel authPriv
defAuthType MD5
defPrivType DES
defAuthPassphrase pass
defPrivPassphrase pass
I'm already using this user and resource to successfully perform the snmpget with python (pysnmp) and bash (snmpget), so I can definitely tell that my setup works and the java code is the problem.
I have two java classes (Listener.java and ServerStatusHelper.java)
Listener.java contains main and calls the snmpGet inside ServerStatusHelper.java, other code of Listener is excluded as its not neccessary.
import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.AuthSHA;
import org.snmp4j.security.PrivAES128;
import org.snmp4j.security.PrivDES;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.VariableBinding;
public class Listener {
public static void main(String[] args) {
ServerStatusHelper agent = new ServerStatusHelper("host.tld", "udp", 161, "demo", "demo",
"pass", "pass", new AuthMD5(), new PrivDES(), true);
try {
agent.startAgent();
ResponseEvent response = agent.snmpGetOperation(SnmpConstants.sysUpTime);
if (response != null) {
System.out.println(
"response null - error: "+ response.getError() +
"peerAddress: " + response.getPeerAddress() +
"source: " + response.getSource().toString() +
"request: " + response.getRequest());
}
} catch (
IOException e) {
e.printStackTrace();
}
}
}
ServerStatusHelper.java
import java.io.IOException;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.UserTarget;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthGeneric;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.PrivDES;
import org.snmp4j.security.PrivacyGeneric;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TransportIpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;
public class ServerStatusHelper {
private Address nmsIP;
private String user;
private String securityName;
private String privacyPassword;
private String authorizationPassword;
private AuthGeneric authProtocol;
private PrivacyGeneric privacyProtocol;
private String protocol;
private boolean encryption;
private long timeOut = 1000;
private int noOfRetries = 10;
private Snmp snmp;
private UserTarget target;
private CommunityTarget v1target;
ServerStatusHelper(String ip, String protocol, int snmpPort, String username, String securityName,
String privacyPassword, String authPassowrd, AuthGeneric authProtocol, PrivacyGeneric privacyProtocol,
boolean encryption) {
nmsIP = GenericAddress.parse(protocol + ":" + ip + "/" + snmpPort);
System.out.println("NMS IP set : " + nmsIP.toString());
this.protocol = protocol;
this.user = username;
this.securityName = securityName;
this.privacyPassword = privacyPassword;
this.authorizationPassword = authPassowrd;
this.authProtocol = authProtocol;
this.privacyProtocol = privacyProtocol;
this.encryption = encryption;
SecurityProtocols.getInstance().addAuthenticationProtocol(new AuthMD5());
SecurityProtocols.getInstance().addPrivacyProtocol(new PrivDES());
}
public void startAgent() throws IOException {
if (snmp == null) {
TransportMapping<? extends TransportIpAddress> transport = null;
if (protocol.equalsIgnoreCase("udp")) {
System.out.println("UDP Protocol selected.");
transport = new DefaultUdpTransportMapping();
} else {
System.out.println("TCP Protocol selected.");
transport = new DefaultTcpTransportMapping();
}
snmp = new Snmp(transport);
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
transport.listen();
snmp.getUSM().addUser(new OctetString(user),
new UsmUser(new OctetString(securityName), authProtocol.getID(),
new OctetString(authorizationPassword), privacyProtocol.getID(),
new OctetString(privacyPassword)));
if (encryption)
target = createUserTarget();
else
v1target = createUserTargetWithoutEncryption();
}
}
public ResponseEvent snmpSetOperation(VariableBinding[] vars) throws IOException {
PDU setPdu = new ScopedPDU();
for (VariableBinding variableBinding : vars) {
setPdu.add(variableBinding);
}
return snmp.send(setPdu, target);
}
public ResponseEvent snmpGetOperation(OID oid) throws IOException {
if (encryption) {
PDU getPdu = new ScopedPDU();
getPdu.add(new VariableBinding(oid));
getPdu.setType(ScopedPDU.GET);
return snmp.get(getPdu, target);
} else {
PDU getPdu = new PDU();
getPdu.add(new VariableBinding(oid));
getPdu.setType(PDU.GET);
return snmp.get(getPdu, v1target);
}
}
private UserTarget createUserTarget() {
UserTarget target = new UserTarget();
target.setAddress(nmsIP);
target.setRetries(noOfRetries);
target.setTimeout(timeOut);
target.setVersion(SnmpConstants.version3);
target.setSecurityLevel(SecurityLevel.AUTH_PRIV);
target.setSecurityName(new OctetString(securityName));
return target;
}
private CommunityTarget createUserTargetWithoutEncryption() {
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("public"));
target.setAddress(nmsIP);
target.setRetries(noOfRetries);
target.setTimeout(timeOut);
target.setVersion(SnmpConstants.version1);
return target;
}
public long getTimeOut() {
return timeOut;
}
public void setTimeOut(long timeOut) {
this.timeOut = timeOut;
}
public int getNoOfRetries() {
return noOfRetries;
}
public void setNoOfRetries(int noOfRetries) {
this.noOfRetries = noOfRetries;
}
}
The execution of the program exits with
NMS IP set : **IPREMOVED**/161
UDP Protocol selected.
response null - error: nullpeerAddress: **IPREMOVED**/161source: org.snmp4j.Snmp#e580929 request: GET[{contextEngineID=80:00:1f:88:80:5e:2e:49:07:2f:68:44:57:00:00:00:00, contextName=}, requestID=588252045, errorStatus=0, errorIndex=0, VBS[1.3.6.1.2.1.1.3.0 = Null]]
Anyone has an idea what I'm doing wrong?
Edit:
From the servers syslog I can see, that the request arrives at the resource:
Jul 31 11:52:46 loadbalancer snmpd[1219]: Connection from UDP: [IP REMOVED]:54734->[IP REMOVED]:161
Jul 31 11:52:46 loadbalancer snmpd[1219]: Connection from UDP: [IP REMOVED]:54734->[IP REMOVED]:161
#i-shm I think you are doing everything ok.
The only problem in your code could be just the line in which you evaluate the response variable. Your are indicating response != null when it should be actually response == null. I mean:
import org.snmp4j.PDU;
import org.snmp4j.ScopedPDU;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.AuthSHA;
import org.snmp4j.security.PrivAES128;
import org.snmp4j.security.PrivDES;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.VariableBinding;
public class Listener {
public static void main(String[] args) {
ServerStatusHelper agent = new ServerStatusHelper("host.tld", "udp", 161, "demo", "demo",
"pass", "pass", new AuthMD5(), new PrivDES(), true);
try {
agent.startAgent();
ResponseEvent event = agent.snmpGetOperation(SnmpConstants.sysUpTime);
final PDU response = event.getResponse();
if (response == null) {
System.out.println(
"response null - error: "+ event.getError() +
"peerAddress: " + event.getPeerAddress() +
"source: " + event.getSource().toString() +
"request: " + event.getRequest());
} else {
System.out.println("Response PDU:" + response.toString());
// Process the response as you need, maybe something like this:
long sysUpTime = response.get(0).getVariable().toLong();
// You can find relevant information in the javadocs of the library:
// https://agentpp.com/doc/snmp4j/index.html?org/snmp4j/package-summary.html
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is why you do not receive errors in the java code and your syslog indicates that the requests were actually sent.
I'm trying to automate registration on a website but that site send OTP to the email. so I need to fetch the OTP from the mail and print it to text field.
I am using this code but it's not showing unread message count and the OTP verification mail.
Can anyone help with how can I extract OTP from the email and submit it on the website ?
package MAVEN.GmailIMAP;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Properties;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Store;
public class Gmail3 {
public static void ReceiveMail(String FolderName,String SubjectContent, String emailContent, int lengthOfOTP){
String hostName = "imap.gmail.com";//change it according to your mail
String username = "test12345#gmail.com";//username
String password = "test12345"; //password
int messageCount;
int unreadMsgCount;
String emailSubject;
Message emailMessage;
String searchText=null ;
Properties sysProps = System.getProperties();
sysProps.setProperty("mail.store.protocol", "imaps");
try {
Session session = Session.getInstance(sysProps, null);
Store store = session.getStore();
store.connect(hostName, username, password);
Folder emailBox = store.getFolder(FolderName);
emailBox.open(Folder.READ_ONLY);
messageCount = emailBox.getMessageCount();
System.out.println("Total Message Count: " + messageCount);
unreadMsgCount = emailBox.getNewMessageCount();
System.out.println("Unread Emails count:" + unreadMsgCount);
for(int i=messageCount; i>(messageCount-unreadMsgCount); i--)
{
emailMessage = emailBox.getMessage(i);
emailSubject = emailMessage.getSubject();
if(emailSubject.contains(SubjectContent))
{
System.out.println("OTP mail found");
String line;
StringBuffer buffer = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(emailMessage.getInputStream()));
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String messageContent=emailContent;
String result = buffer.toString().substring(buffer.toString().indexOf(messageContent));
searchText = result.substring(messageContent.length(), messageContent.length()+lengthOfOTP);
System.out.println("Text found : "+ searchText);
emailMessage.setFlag(Flags.Flag.SEEN, true);
break;
}
emailMessage.setFlag(Flags.Flag.SEEN, true);
}
emailBox.close(true);
store.close();
} catch (Exception mex) {
mex.printStackTrace();
System.out.println("OTP Not found ");
}
return searchText ;
}
public static void main(String[] args) {
ReceiveMail("FolderName","SubjectContent","One Time Password (OTP):",6);
}
}
Below Email body scanner should work for the input which you are looking for
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class OtpRegex {
public static void main(String[] args) {
// String regex = "((is|otp|password|key|code|CODE|KEY|OTP|PASSWORD|Do).[0-9]{4,8}.(is|otp|password|key|code|CODE|KEY|OTP|PASSWORD)?)|(^[0-9]{4,8}.(is|otp|password|key|code|CODE|KEY|OTP|PASSWORD))";
String text = "To auth... \n\n869256\n\n Do is your login OTP. Treat this as confidential. Sharing it with anyone gives them full access to your Paytm Wallet. Paytm never calls to verify your OTP.";
Scanner sc = new Scanner(text);
int otp = -1;
String line = null;
while (sc.hasNextLine()) {
line = sc.nextLine().trim();
try{
otp = Integer.parseInt(line);
break;
} catch (NumberFormatException nfx) {
//Ignore the exception
}
}
System.out.println(otp);
}
}
I tried to fetch email using message driven bean. My intention is to capture the new emails. I have used Jboss 6.1. I enabled the pop3s in my gmail. When i start the server able to fetch the existing emails from inbox.
Once the server stated up and application is running, the new email are not notified by MailListener. i tried by adding the polling interval as well.
Any suggestions.
package uk.co.test.inbound;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.inject.Named;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Message.RecipientType;
import org.jboss.ejb3.annotation.ResourceAdapter;
import org.jboss.resource.adapter.mail.inflow.MailListener;
#MessageDriven(
activationConfig = {
#ActivationConfigProperty(propertyName = "mailServer", propertyValue = "pop.gmail.com"),
#ActivationConfigProperty(propertyName = "mailFolder", propertyValue = "INBOX"),
#ActivationConfigProperty(propertyName = "storeProtocol", propertyValue = "pop3s"),
#ActivationConfigProperty(propertyName = "userName", propertyValue = "xxxx#gmail.com"),
#ActivationConfigProperty(propertyName= "password", propertyValue="xxxxx"),
#ActivationConfigProperty(propertyName= "pollingInterval", propertyValue="100"),
#ActivationConfigProperty(propertyName= "port", propertyValue="995"),
#ActivationConfigProperty(propertyName= "debug", propertyValue="true"),
#ActivationConfigProperty(propertyName= "starttls", propertyValue="true")
})
#ResourceAdapter("mail-ra.rar")
#Named("mailListener")
public class EmailReceiver implements MailListener{
#Override
public void onMessage(Message msg) {
System.out.println("One new Message Received" );
try {
Address[] fromAddress = msg.getFrom();
String from = fromAddress[0].toString();
String subject = msg.getSubject();
String toList = parseAddresses(msg.getRecipients(RecipientType.TO));
String ccList = parseAddresses(msg.getRecipients(RecipientType.CC));
String sentDate = msg.getSentDate().toString();
String contentType = msg.getContentType();
String messageContent = "";
if (contentType.contains("text/plain") || contentType.contains("text/html")) {
try {
Object content = msg.getContent();
if (content != null) {
messageContent = content.toString();
}
} catch (Exception ex) {
messageContent = "[Error downloading content]";
ex.printStackTrace();
}
} else {
try {
if (msg.getContent() instanceof Multipart) {
Multipart content = (Multipart) msg.getContent();
content.getCount();
Part part = content.getBodyPart(0);
InputStream is = part.getInputStream();
if (!(is instanceof BufferedInputStream)) {
is = new BufferedInputStream(is);
}
int c;
final StringWriter sw = new StringWriter();
while ((c = is.read()) != -1) {
sw.write(c);
}
if (!sw.toString().contains("<div>")) {
messageContent = sw.toString();
}
}
} catch (IOException e) {
messageContent = "[Error downloading content]";
e.printStackTrace();
}
}
System.out.println("\t Subject: " + subject);
System.out.println("\t Message: " + messageContent);
} catch (MessagingException e) {
e.printStackTrace();
}
}
/**
* Returns a list of addresses in String format separated by comma
*
* #param address an array of Address objects
* #return a string represents a list of addresses
*/
private String parseAddresses(Address[] address) {
String listAddress = "";
if (address != null) {
for (int i = 0; i < address.length; i++) {
listAddress += address[i].toString() + ", ";
}
}
if (listAddress.length() > 1) {
listAddress = listAddress.substring(0, listAddress.length() - 2);
}
return listAddress;
}
}
Problem might be linked to this bug: https://issues.redhat.com/browse/JBAS-8635
There is a "fixed" mail-ra.jar file provided (don't know if it can be trusted). In the comments they state they only added a "setReleased" to the existing mail-ra.jar. Someone tested it and they confirmed it worked.
There is also a manual implementation example in the last comment on the ticket. Implementing it that way will give you more controll.
I started to read about for in join in Java so I goal is to verify messages in JavaMail which has attatchement.
I´m doubt if it´s rigth. Because I saw some tutorial spliting the array in the 2 parts for each lopp. I put my all class code here below to demonstrate what I did.
package service.forkinjoin;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.RecursiveTask;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.MimeBodyPart;
import service.FileUtil;
public class SepareteMessagesProcess extends RecursiveTask<List<Message>> {
private static final long serialVersionUID = 7126215365819834781L;
private List<Message> listMessages;
private static List<Message> listMessagesToDelete = new ArrayList<>();
private final int threadCount = Runtime.getRuntime().availableProcessors();
public SepareteMessagesProcess(List<Message> listMessages) {
this.listMessages = listMessages;
}
#Override
protected List<Message> compute() {
if (this.listMessages.size() <= threadCount) {
try {
this.separateMessages(this.listMessages);
} catch (MessagingException | IOException e) {
e.printStackTrace();
}
} else {
int[] arrayMaxIndex = this.generateIndexs(this.listMessages);
List<SepareteMessagesProcess> list = this.splitList(this.listMessages, arrayMaxIndex);
invokeAll(list);
}
return listMessagesToDelete;
}
private void separateMessages(List<Message> listMessages) throws MessagingException, IOException {
for (Iterator<Message> iterator = listMessages.iterator(); iterator.hasNext();) {
Message message = (Message) iterator.next();
if ((this.hasNoAttachment(message.getContentType()) || (this.hasNoXmlAttachment(message)))) {
listMessagesToDelete.add(message);
}
}
}
private List<SepareteMessagesProcess> splitList(List<Message> listMessages, int[] arrayMaxIndex) {
List<SepareteMessagesProcess> list = new ArrayList<>(this.threadCount);
int end = 0;
int start = 0;
for (int i = 0; i < this.threadCount; i++) {
end += (arrayMaxIndex[i]);
list.add(new SepareteMessagesProcess(listMessages.subList(start, end)));
start += arrayMaxIndex[i];
}
return list;
}
private int[] generateIndexs(List<Message> listMessages) {
int value = listMessages.size() / this.threadCount;
int[] arrayMaxIndex = new int[this.threadCount];
for (int i = 0; i < this.threadCount; i++) {
arrayMaxIndex[i] = value;
}
arrayMaxIndex[this.threadCount - 1] += listMessages.size() % threadCount;
return arrayMaxIndex;
}
private boolean hasNoAttachment(String content) {
return !content.contains("multipart/MIXED");
}
private boolean hasNoXmlAttachment(Message message) throws IOException, MessagingException {
Multipart multipart = (Multipart) message.getContent();
for (int i = 0; i < multipart.getCount(); i++) {
MimeBodyPart mimeBodyPart = (MimeBodyPart) multipart.getBodyPart(i);
if (Part.ATTACHMENT.equalsIgnoreCase(mimeBodyPart.getDisposition())) {
if (FileUtil.isXmlFile(mimeBodyPart.getFileName())) {
return false;
}
}
}
return true;
}
}
No. Rather than rewrite the tutorial here, just follow the example it gives, such as:
if (problem is small)
directly solve problem
else {
split problem into independent parts
fork new subtasks to solve each part
join all subtasks
compose result from subresults
}