Using Java Desktop mailto for two recipients - java

I am trying to add a feedback button to a Java program for work. I want this button to actually send an email to myself and one other person. All employees have the same default email application so using the Desktop mail method works fine.
I managed to get this working with 1 email addressee. It properly opens the email client, starts a new email and puts the addressee in the address line. The problem is when I try to add two email addresses.
int result = JOptionPane.showOptionDialog(null, panel, "Feedback", JOptionPane.YES_NO_OPTION,
JOptionPane.INFORMATION_MESSAGE, null, options1, null);
if(result == JOptionPane.NO_OPTION){
try {
Desktop.getDesktop().mail(new URI("mailto:Chuck.Norris#yahoo.com"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
So doing it like that works perfectly.
I've tried simply separating the addresses with a comma like this:
Desktop.getDesktop().mail(new URI("mailto:Chuck.Norris#yahoo.com","Bill.Clinton#gmail.com"));
but this gives me an error and the only option is to actually remove the second argument.
Finally I've tried using a String[] like this:
String[] mailAddressTo = {"Chuck.Norris#yahoo.com","Bill.Clinton#gmail.com"};
and then inserting that into the mailto method like this:
Desktop.getDesktop().mail(new URI("mailto:"+mailAddressTo));
but the email address comes out being
[Ljava.lang.String; #5e9394f7
once the email client is opened.
I've tried searching online and while I did find some solutions in regards to sending mail using Java through other methods than Desktop.mail - I found nothing related to how to accomplish this with Desktop.
If anyone can let me know how to make this work I would greatly appreciate it!

It helps to look at the documentation instead of guessing.
The list of URI constructors shows that there is no URI constructor which takes two Strings. That is why your first approach failed.
In Java, all arrays extend Object and inherit the default toString method of Object. Concatenating objects with + automatically invokes each object’s toString method, which is why your second approach yielded the results it did.
The official definition of the format of mailto: URLs is RFC 2368, which states that multiple recipients can be specified by separating with commas. So, you were on the right track.
As of Java 8, you can simply join your addresses with String.join:
String[] mailAddressTo = {"Chuck.Norris#yahoo.com","Bill.Clinton#gmail.com"};
Desktop.getDesktop().mail(new URI("mailto:" + String.join(",", mailAddressTo)));
However, the documentation of the URI class states that the single-argument constructor assumes its String argument is already properly escaped. While it’s true that the example e-mail addresses you’ve provided don’t need to be escaped, it’s not safe to make that assumption with all possible addresses. To deal with this, you can use a multiple-argument URI constructor that will do the correct URI-escaping for you:
String[] mailAddressTo = { "Chuck.Norris#yahoo.com", "Bill.Clinton#gmail.com" };
Desktop.getDesktop().mail(new URI("mailto", String.join(",", mailAddressTo), null));
If you’re using a version of Java older than 8, you can build the string yourself:
String[] mailAddressTo = { "Chuck.Norris#yahoo.com", "Bill.Clinton#gmail.com" };
StringBuilder addressList = new StringBuilder();
String separator = "";
for (String address : mailAddressTo) {
addressList.append(separator).append(address);
separator = ",";
}
Desktop.getDesktop().mail(new URI("mailto", addressList.toString(), null));

Related

Downloading attachments from unseen messages

I work on university project in java. I have to download attachments from new emails using GMAIL API.
I successfully connected to gmail account using OAuth 2.0 authorization.
private static final List<String> SCOPES = Collections.singletonList(GmailScopes.GMAIL_READONLY);
I tried to get unseen mails using
ListMessagesResponse listMessageResponse = service.users().messages().list(user).setQ("is:unseen").execute();
listMessageResponse is not null but when I call method .getResultSizeEstimate() it returns 0
also I tried to convert listMessageResponse to List < Message > (I guess this is more usable) using
List<Message> list = listMessageResponse.getMessages();
But list launches NullPointerException
Then tried to get each attachment with
for(Message m : list) {
List<MessagePart> part = m.getPayload().getParts();
for(MessagePart p: part) {
if(p.getFilename()!=null && p.getFilename().length()>0) {
System.out.println(p.getFilename()); // Just to check attachment filename
}
}
}
Is my approach correct (if not how to fix it) and how should I download those attachments.
EDIT 1:
Fixed q parameter, I mistakenly wrote is:unseen instead of is:unread.
Now app reaches unread mails successfully.
(For example there was two unread mails and both successfully reached, I can get theirs IDs easy).
Now this part trows NullPointerException
List<MessagePart> part = m.getPayload().getParts();
Both messages have attachments and m is not null (I get ID with .getID())
Any ideas how to overcome this and download attachment?
EDIT 2:
Attachments Downloading part
for(MessagePart p : parts) {
if ((p.getFilename() != null && p.getFilename().length() > 0)) {
String filename = p.getFilename();
String attId = p.getBody().getAttachmentId();
MessagePartBody attachPart;
FileOutputStream fileOutFile = null;
try {
attachPart = service.users().messages().attachments().get("me", p.getPartId(), attId).execute();
byte[] fileByteArray = Base64.decodeBase64(attachPart.getData());
fileOutFile = new FileOutputStream(filename); // Or any other dir
fileOutFile.write(fileByteArray);
fileOutFile.close();
}catch (IOException e) {
System.out.println("IO Exception processing attachment: " + filename);
} finally {
if (fileOutFile != null) {
try {
fileOutFile.close();
} catch (IOException e) {
// probably doesn't matter
}
}
}
}
}
Downloading working like charm, tested app with different type of emails.
Only thing left is to change label of unread message (that was reached by app) to read. Any tips how to do it?
And one tiny question:
I want this app to fetch mails on every 10 minutes using TimerTask abstract class. Is there need for manual "closing" of connection with gmail or that's done automatically after run() method iteration ends?
#Override
public void run(){
// Some fancy code
service.close(); // Something like that if even exists
}
I don't think ListMessagesResponse ever becomes null. Even if there are no messages that match your query, at least resultSizeEstimate will get populated in the resulting response: see Users.messages: list > Response.
I think you are using the correct approach, just that there is no message that matches your query. Actually, I never saw is:unseen before. Did you mean is:unread instead?
Update:
When using Users.messages: list only the id and the threadId of each message is populated, so you cannot access the message payload. In order to get the full message resource, you have to use Users.messages: get instead, as you can see in the referenced link:
Note that each message resource contains only an id and a threadId. Additional message details can be fetched using the messages.get method.
So in this case, after getting the list of messages, you have to iterate through the list, and do the following for each message in the list:
Get the message id via m.getId().
Once you have retrieved the message id, use it to call Gmail.Users.Messages.Get and get the full message resource. The retrieved message should have all fields populated, including payload, and you should be able to access the corresponding attachments.
Code sample:
List<Message> list = listMessageResponse.getMessages();
for(Message m : list) {
Message message = service.users().messages().get(user, m.getId()).execute();
List<MessagePart> part = message.getPayload().getParts();
// Rest of code
}
Reference:
Class ListMessagesResponse
Users.messages: list > Response

email validation in java which removes email like #localhost.com, user#9.8.7.6

To validate email I am using following method i.e. official java email package
public static boolean isValidEmailAddress(String email) {
boolean result = true;
try {
InternetAddress emailAddr = new InternetAddress(email);
emailAddr.validate();
} catch (AddressException ex) {
result = false;
}
return result;
}
But above method also considers true for even "user#localhost.com", "user#10.9.8.7? I will be grateful if someone please help me out in removing above all these while validating email id of a user? I searched in google but could not find any solution. Many thanks in advance
The official Java email package considers things like user#localhost.com and user#10.9.8.7 as valid email addresses, since they are according to the RFC. Like the people who commented said, it would be best to figure out what rules you're trying to implement for your validation and go from there.

CSS validation with AntiSamy

I have a String, and I want to validate whether it is a valid CSS value or not. In the documentation of AntiSamy, I found that I might be able to use CSSValidator.isValidProperty (http://javadox.com/org.owasp/antisamy/1.4/org/owasp/validator/css/CssValidator) to do so. However, the type of the second param requires LexicalUnit.
Is there another way to validate a String with AnitSamy?
I think what you want is the CssScanner.
/****** pull out style tag from html *****/
Pattern p = Pattern.compile("<style>([\\s\\S]+?)</style>");
Matcher m = p.matcher(validHTML);
// if we find a match, get the group
if (m.find()) {
// get the matching group
codeGroup = m.group(1);
}
/****** block for checking all css for validity *****/
InternalPolicy policy = null;
try {
policy = (InternalPolicy) InternalPolicy.getInstance("antisamy-ebay.xml");
} catch (PolicyException e) {
e.printStackTrace();
}
ResourceBundle messages = ResourceBundle.getBundle("AntiSamy", Locale.getDefault());
CssScanner scanner = new CssScanner(policy, messages);
CleanResults results = scanner.scanStyleSheet(codeGroup, Integer.MAX_VALUE);
validCSS = results.getCleanHTML().toString();
That is the part of the code that worked for me. Let me know if any of this does not work for you, I have variables declared at the top of the code because I am also handling html validation in here too. So some variables are not in this code. But it should point you in the right direction. Also, you need a policy in place, I chose the ebay policy, this guides the whitelist of what the css will allow for the resulting output. I have not used the CssValidator, so I am not sure how they compare, but CssScanner does a great job of giving back clean css.

"Cast" a String Attribute to String Java [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I have a little problem with Attributes. I am currently working on a project that parses emails from an LDAP server into the Java application that will be doing some interesting stuff with emails in the future.
I am currently having this code that takes emails from users on LDAP and it needs to put emails in the User class as seen in my code:
[some code here, TRY CATCH is also included]
LdapContext ctx = new InitialLdapContext(env, null);
ctx.setRequestControls(null);
NamingEnumeration<?> namingEnum2 = ctx.search("[path to the server]", "(objectClass=user)", getSimpleSearchControls());
System.out.println("Test: print emails from whole DIRECOTRY: \n");
while (namingEnum2.hasMore()) {
SearchResult result = (SearchResult) namingEnum2.next();
Attributes attrs = result.getAttributes();
System.out.println(attrs.get("mail"));
/** This line above works fine, but every time there is no email
in User info, it prints "null" in some cases when there is
no email, which is not perfect. But this is just here to see
if everything works and indeed it does.**/
/**User Class accepts a String parameter, checks if it's empty
and all that, does some checking and etc... BUT! attrs.get("mail")
is an Attribute, NOT a String. And I need to somehow "cast" this
attribute to a String, so I can work with it.**/
User user = new User(attrs.get("mail")); //error yet,because the parameter is not a String.
User user = new User(attrs.get("mail").toString());//gives an expeption.
/** And I know that there is a toString() method in Attribute Class,
but it doesn't work, it gives an "java.lang.NullPointerException"
exception when I use it as attrs.get("mail").toString() **/
}
Here is User class's constructor:
public User(String mail){
eMail = "NO EMAIL!";
if (mail != null && !mail.isEmpty()){
eMail = mail;
}
else
{
eMail = "NO EMAIL!";
}
}
try this
User user = new User(attrs.get("mail")!=null?attrs.get("mail").toString():null);
First you need to check that given attribute exists by using != null (e.g. using Objects.toString which does that inside, or manual if) check, and then use either toString on the Attribute, just like println does inside:
User user = new User(Objects.toString(attrs.get("mail")));
Or you can also use (to retrieve a single value in the attribute, if you have many you need to use getAll):
Object mail = null;
if (attrs.get("mail") != null) {
mail = attrs.get("mail").get();
}
User user = new User(mail.toString());

Lotus Notes - Mail Document - Principal/From,INetFrom, SentTime, ReceivedTime fields

I have a requirement to fetch the SenderName,SenderEmail,ToNames,ToEmails,CCNames,CcEmails from a lotus notes document instance.
Issue1
Looking into lotus.domino.Document API I found out the method getItems. When I write the elements to the system.out values for SenderEmail, ToEmails and CcEmails can be found.
However values for SenderName(a.k.a From), ToNames cannot be derived that easily.
The values seems to be using an common name format. For example check check my system.output below.
Principal = "CN=Amaw Scritz/O=fictive"
$MessageID = "<OF0FF3779B.36590F8A-ON80257D15.001DBC47-65257D15.001DC804#LocalDomain>"
INetFrom = "AmawScritz#fictive.com"
Recipients = "CN=Girl1/O=fictive#fictive"
MailOptions = "0"
SaveOptions = "1"
From = "CN=Amaw Scritz/O=fictive"
AltFrom = "CN=Amaw Scritz/O=fictive"
SendTo = "CN=Girl1/O=fictive#fictive"
CopyTo = "CN=Girl2/O=fictive#fictive"
BlindCopyTo = ""
InetSendTo = "Girl1#fictive.com"
InetCopyTo = "Girl2#fictive.com"
$Abstract = "sasdasda"
$UpdatedBy = "CN=Amaw Scritz/O=fictive"
Body = "Hello World"
The question is how can I get 'Amaw Scritz' from the common name 'CN=Amaw Scritz/O=fictive'. Is there any look up mechanism that can be used. (I would prefer to have a option other than doing a substring of the common name)
Issue2
is it possible to retrieve SentTime and ReceivedTime from mail document instance?
I know that there are two methods called getCreated and getLastModified. getCreated can be loosely associated with the SentTime and getLastModified can be loosely associated with ReceivedTime. Are there are other ways to get times for SentTime and ReceivedTime.
Issue3
How can one distinguish whether a mail document is a Sent mail or a Received Mail?
Issue1
You can use Name class.
Here example from this link:
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
// Create a hierarchical name
Name nam = session.createName(
"CN=John B Goode/OU=Sales/OU=East/O=Acme/C=US");
// Returns:
// John B Goode
// John B Goode/Sales/East/Acme/US
// CN=John B Goode/OU=Sales/OU=East/O=Acme/C=US
System.out.println(nam.getCommon());
System.out.println(nam.getAbbreviated());
System.out.println(nam.getCanonical());
} catch(Exception e) {
e.printStackTrace();
}
}
}
Issue2
Use values of PostedDate field and DeliveredDate field of mail document.
Issue3
Check that $Inbox folder contains your mail document. Or take a look at Dave Delay answer.
I agree with #nempoBu4 on Issues 1 and 2. I disagree with the answer to Issue 3. A received message can be removed from the inbox, so checking $Inbox doesn't help you distinguish between sent and received messages.
Assuming you have the document open, the best approach is to check two items. Sent and received messages both have a PostedDate item, but only a received message has a DeliveredDate item. Incidentally, a draft message has neither PostedDate or DeliveredDate.

Categories