Java Mail: get UniqueID from Message - java

I need a uniqueID from a message Object to save this in my database.
Afterwards I´m able to search for this UID in my database and can add other properties, like "emailTrackingActive" etc.
a) Is there a possibility to get a whole UID for a Email Inbox or is it always only per folder? Currently I´m getting this as you can see in the code.
Currently I´m doing the following as you can see in the code:
After I´ve send the message, I copy the message into my "Sent" folder and then I want to get the UID and save it in the database.
With "EmailHelperClass" I´m getting Store etc.
I think it should be clear and I will not post this code...
private void copyIntoSentAndSaveInDatabase(EmailHelperClass email, final Message msg){
final Store store = email.getMailConfiguration().getWriteStore();
final Folder folder = (Folder) store.getFolder("Sent");
if (folder.exists() == false) {
folder.create(Folder.HOLDS_MESSAGES);
}
folder.open(Folder.READ_WRITE);
folder.appendMessages(new Message[] { msg });
// Get UniqueID
UIDFolder uf = (UIDFolder) folder;
Long messageId = uf.getUID(msg);
// Todo Update in DB etc
}
But now I´m getting the following error message:
java.util.NoSuchElementException: Message does not belong to this
folder
What is wrong here?

Hi all you need to change folder to IMAPFolder
final Store store = email.getMailConfiguration().getWriteStore();
final IMAPFolder folder = (IMAPFolder) store.getFolder("Sent");
folder.open(Folder.READ_WRITE)
with the help of this folder fetch all your messages i have write the below method to get the UID of the message
private long getMessagesUID(UIDFolder folder,javax.mail.message message){
try{
return folder.getUID(message)
}catch(Exception ex)
{
ex.printStackTrace();
}
Let me know in case of any query.

Related

Configure Notification in MultipartUploadRequest

I m implementing 'net.gotev:uploadservice:4.5.1' to upload image to my server. I wrote below code but getting exception message Notification is not configured so file is not uploading. When i tried to configure notification using setNotificationConfig(new UploadNotificationConfig()), It ask for 6 Arguments to be passed in New UploadNotificationConfig().
Here is my complete code.
try {
String uploadId = UUID.randomUUID().toString();
//Creating a multi part request
new MultipartUploadRequest(this, upload_path)
.addFileToUpload(currentPhotoPath, "image") //Adding file
.addParameter("name", image_file_name) //Adding text parameter to the request
.setMaxRetries(2).setNotificationConfig(new UploadNotificationConfig())
.setUploadID(uploadId)
.startUpload(); //Starting the upload
} catch (Exception exc) {
Toast.makeText(this, exc.getMessage(), Toast.LENGTH_SHORT).show();
}
I tried but could not succeed to pass required arguments and get the method working. Can someone help to fix this.
Also attached image explaining kind of argument required. I understand first 2 but for other 4, not geting any idea how to work.

Azure BlobNotFound when downloading in SpringBoot app

I have a task to make possibility to download simple .txt files from the application using Azure Blob Storage. The code is supposed to work. I didn't write it, but it looks OK to me and from what I'll show later in this post, it really connects to the Azure, and, what's more important, it really works only when I'm testing the app on localhost, but not on the publicly available site.
These are the steps I made:
uploaded files to the storage (the underlined is one of them):
added proper link to the button that should download the attachment via REST API
of course, I've also added reference to the attachment in the database (its ID, name etc.)
here's how it looks on frontend:
And this is what I get:
I've seen somewhere that it might be caused by Azure CORS settings that don't allow the app to access the storage. Here's what I've done so far:
went to portal.azure.com and changed CORS settings like this:
found something about putting some code into the app under this Microsoft link, but it's not Java. I guess there are some analogical ways in Java:
https://blogs.msdn.microsoft.com/windowsazurestorage/2014/02/03/windows-azure-storage-introducing-cors/ . Is it necessary after the CORS rules have been added in the Azure Portal?
Also, I've found information that it may be caused by the storage access permissions. The Public Access Level is set to Container:
Not sure if it gives anything, but these are the container's properties:
What else can be the problem with the BlobNotFound error I receive? Hope I've put enough information here, but if some more is needed say in comment and I'll provide it.
This is the code that's supposed to download the attachment of this method, contained in 3 classes:
Controller class part:
#GetMapping("/download/{id}")
#ResponseStatus(HttpStatus.OK)
public void downloadAttachment(#PathVariable long id, HttpServletResponse response) throws IOException {
dataUploadRequestAttachmentService.downloadStaticAttachment(response, id);
}
Controller service class part:
public void downloadStaticAttachment(HttpServletResponse response, long id) throws IOException {
ArticleAttachment articleAttachment = this.findAttachment(id);
String mimeType = URLConnection.guessContentTypeFromName(articleAttachment.getName());
if (mimeType == null){
mimeType = "application/octet-stream";
}
response.setContentType(mimeType);
response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", articleAttachment.getName()));
azureBlobStorageArticleAttachmentService.downloadArticleAttachment(
articleAttachment.getName(),
articleAttachment.getId(),
response.getOutputStream()
);
}
And the AzureBlobStorageArticleAttachmentService class:
public void downloadArticleAttachment(String attachmentName, Long articleId, OutputStream outputStream) {
try {
CloudBlockBlob blob = container.getBlockBlobReference(String.format("%s_%s", articleId, attachmentName));
blob.download(outputStream);
} catch (URISyntaxException | StorageException e) {
e.printStackTrace();
log.error(String.format("Download article attachment %s error", attachmentName));
}
}
According to your description, please debug to check if you get the correct blob name in the code: CloudBlockBlob blob = container.getBlockBlobReference(String.format("%s_%s", articleId, attachmentName));
Here is a demo about how to download blobs using Java SDK for your reference:
/// <summary>
/// download blob to memory
/// </summary>
/// <param name="containerName">blob container name</param>
/// <param name="blobName">blob Name</param>
public static ByteArrayOutputStream downloadBlobToMemory(String containerName, String blobName) {
CloudStorageAccount account = null;
CloudBlobContainer container = null;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
account = CloudStorageAccount.parse(ConnString);
CloudBlobClient client = account.createCloudBlobClient();
container = client.getContainerReference(containerName);
container.createIfNotExists();
CloudBlockBlob cloudBlockBlob = container.getBlockBlobReference(blobName);
byteArrayOutputStream=new ByteArrayOutputStream();
cloudBlockBlob.download(byteArrayOutputStream);
}catch(Exception ex) {
ex.printStackTrace();
}
return byteArrayOutputStream;
}
/// <summary>
/// download blob to local disk
/// </summary>
/// <param name="containerName">blob container name</param>
/// <param name="blobName">blob Name</param>
/// <param name="filePath"> for example: C:\\Test\test.txt</param>
public static void downloadBlobToDisk(String containerName, String blobName, String filePath) {
CloudStorageAccount account = null;
CloudBlobContainer container = null;
try {
account = CloudStorageAccount.parse(ConnString);
CloudBlobClient client = account.createCloudBlobClient();
container = client.getContainerReference(containerName);
container.createIfNotExists();
CloudBlockBlob cloudBlockBlob = container.getBlockBlobReference(blobName);
FileOutputStream fileOutputStream=new FileOutputStream(filePath);
cloudBlockBlob.download(fileOutputStream);
}catch(Exception ex) {
ex.printStackTrace();
}
}
Lee Liu's suggestion about the Blob name was correct when I managed to find out the correct application address. It turned out that domain address visible by user was ending with "azureedge.net", but there's a different one when I went into portal.azure.com. It caused the main problem. After that, I indeed found problem with correct Blob names in storage - because of String.format, I had to add their ID in database with a "_" sign, then they started to be downloaded with content instead of empty files.
It seems that the code was OK, it was the problem with improper address and file names.

Change "from" field in LotusNotes

I'm sending an email using LotusNotes API, what I need to do is to change the "from" field value, please find the code below:
public void sendEmail(String recipient, String subject, String bodyText,String from) throws NotesException {
Session dominoSession = NotesFactory.createSession(dominoServer, dominoUsername, dominoPassword);
Database dominoDb = dominoSession.getDatabase(dominoServer, dominoMailbox);
Document memo = dominoDb.createDocument();
memo.appendItemValue("Form", "Memo");
memo.appendItemValue("Importance", "1");
memo.appendItemValue("Subject", subject);
memo.appendItemValue("Body", bodyText);
memo.send(false, recipient);
dominoDb.recycle();
dominoSession.recycle();
}
You can't change it. The server always puts the current username into the 'From' field. You can have a different sender in the 'Principal', but the mail will still show who actually sent it.
But there is a workaround: instead of sending the mail put the mail document directly into mail.box on the server. Then you can use the 'From' field content of your choice.
I edited Michele's answer to clarify things a little bit. If you are a beginner, I would not suggest that you use the (undocumented) mail.box approach... You need to know what you are doing there.
I created a mail notification class in Lotusscript a while back, you can take a look at it if you like. Perhaps it will help you.
http://blog.texasswede.com/lotusscript-mail-notification-class/
But again, if you don't know what you are doing, be very very careful... :-)
This is how I solved it, to set the "from" property:
public void sendEmail(final String recipient, final String subject, final String bodyText, final String from) throws NotesException {
final Session dominoSession = NotesFactory.createSession(dominoServer, dominoUsername, dominoPassword);
final Database dominoDb = dominoSession.getDatabase(dominoServer, dominoMailbox);
final Document mail = dominoDb.createDocument();
mail.appendItemValue("Form", "Memo");
mail.appendItemValue("Importance", "1");
mail.appendItemValue("Subject", subject);
mail.appendItemValue("Body", bodyText);
mail.replaceItemValue("From", from + "#NotesDomain");
mail.replaceItemValue("InetFrom", from);
mail.send(false, recipient);
dominoDb.recycle();
dominoSession.recycle();
}

How can I delete a pre-existing image from storage before re-downloading using DownloadManager?

I am writing code for an Android app using Eclipse that is supposed to download an image from a URL (which is generated by the app, elsewhere in the code, using GPS information), then attach the newly downloaded image to an e-mail to be sent. I am able to, in general, accomplish this without much issue.
My problem is this: I only want one image downloaded by the app to be present in the device's external storage at any given time. Deleting the image after the email intent does not work, because because the app doesn't always call onStop or onDestroy when switching to another app to send the email. Time-sensitive deleting of the image will not work either, because I cannot assume that the user will send only one email from the app per hour. I want to give the user the freedom of sending as many of these emails (with one newly downloaded image, each) as they wish.
My current method (which works MOST of the time) is this: in the downloadFile method, simply check for the file's existence (I call it sensorMap.png), then delete it if it exists, before downloading a new one. This SHOULD ensure that there may be only one sensorMap.png image in external storage at any given time (EDIT: it does do this), and that when it comes time to attach the image to the email intent, there will be exactly one image ready to go. Instead, I see that sometimes a second sensorMap image is sometimes being downloaded into storage (i.e. "sensorMap-1.png"), OR the image cannot be attached to the email due to a "File size: 0 bytes" error, OR the image cannot be attached due to a "File does not exist" error. I am unsure what the difference between the latter two problems is. EDIT: Upon manually examining the contents of the directory I created, it seems that, as intended, I end up with only one image titled "sensorMap.png" at a time; it remains in the directory after the app closes, as expected. However, I still occasionally get the "File size: 0 bytes" message or the "File does not exist." message with no attached image, even though I see that the image DOES exist upon looking in directory afterwards. Other times, everything works just fine. It's rather bewildering.
In addition, there is an issue of the button which sends the email becoming unresponsive occasionally. Most of the time, it prompts the user to select an email client, as intended, but occasionally the button will LOOK as if clicked, but do nothing. When this happens, the logcat does not sense that the button was even clicked (I inserted a println statement to test it).
I am unsure of why my delete-before-download is not working flawlessly; the basic idea, at least, appears to be logically sound. Here is the code pertaining to my issue:
Code used to download file (in MainCountActivity.java):
//Function to download image given URL. Will use to attach image file to email.
public void downloadFile(String uRl) {
//delete existing file first so that only one sensorMap image exists in memory
//at any given time.
File file = new File(Environment.getExternalStorageDirectory()+"/SensorLocationImages");
File checkFile = new File(Environment.getExternalStorageDirectory()+"/SensorLocationImages/sensorMap.png");
if(checkFile.exists())
{
//debugging:
System.out.println("About to delete file!");
//deleteFiles(Environment.getExternalStorageDirectory()+"/SensorLocationImages");
checkFile.delete();
}
DownloadManager mgr = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE);
Uri downloadUri = Uri.parse(uRl);
DownloadManager.Request request = new DownloadManager.Request(
downloadUri);
request.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI
| DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false).setTitle("Sensor Location Map")
.setDescription("Pinpointed is the location from which the log file was sent.")
.setDestinationInExternalPublicDir("/SensorLocationImages", "sensorMap.png");
mgr.enqueue(request);
}
public Activity getActivity() //I wasn't sure if this would work, but it did. Or at least appears to.
{ return this; }
Method to send email (in MainCountActivity.java):
public void sendEmail(String toAddress, String ccAddress, String bccAddress, String subject, String body, String attachmentMimeType) throws Exception{
try {
Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
emailIntent.setType(attachmentMimeType); //new
String sToAddress[] = { toAddress };
String sCCAddress[] = { ccAddress};
String sBCCAddress[] = { bccAddress };
emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
emailIntent.putExtra(Intent.EXTRA_EMAIL, sToAddress);
emailIntent.putExtra(android.content.Intent.EXTRA_CC, sCCAddress);
emailIntent.putExtra(android.content.Intent.EXTRA_BCC, sBCCAddress);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, body);
//get URI of logfile
File tempFile = new File(Environment.getExternalStorageDirectory () + MainCountActivity.dirPath);
Uri uri = Uri.fromFile(tempFile);
//create URI arraylist and add first URI
ArrayList<Uri> uris = new ArrayList<Uri>();
uris.add(uri);
//get URI of map image and add to arraylist
//make sure it is there to attach
File file = new File(Environment.getExternalStorageDirectory()+"/SensorLocationImages");
do {
downloadFile(getMapLink());
//createDirectoryAndSaveFile(getBitmapFromURL(getMapLink()), "sensorMap.png");
} while (!file.exists());
uris.add(Uri.fromFile(new File(Environment
.getExternalStorageDirectory()
+ "/SensorLocationImages/sensorMap.png")));
//+ "/sdcard/SensorLocationImages/sensorMap.png")));
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
startActivity(emailIntent);
}
catch(Exception ex) {
ex.printStackTrace();
throw ex;
}
}
OnClick method, for my occasional button issue (In MaincountActivity.java):
public void onClick(View v){
switch(v.getId())
{
case R.id.textView1:
{
break;
}
case R.id.Reset:
{
//allowCounting will let the program know when to let it to count or not, depending if Start or Stop button are pressed.
logCount=0;
mCounter.setText("Total: 0");
mToggle.setChecked(false);
break;
}
/* case R.id.toggleButton:
{
break;
}*/
case R.id.SendEmail:
{
//for debugging purposes:
System.out.println("Email button being clicked!");
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
{
Toast.makeText(this, "GPS is enabled in your device", Toast.LENGTH_SHORT).show();
try {
sendEmail("","","","Sensor Log Info",getEmailBody(),"multipart/mixed");
} catch (Exception e) {
e.printStackTrace();
}
}
else
{
showGPSAlertForEmail();
}
break;
}
}
Basically, I really want to know why my delete-then-download method has not worked every time. Logcat errors have provided no insight. Thank you for your time.

Help in deleting the messages from inbox folder

I'm trying to delete the messages which is selected by user by clicking the checkbox and then clicking the delete button, but I don't understand why my code is not performing the desirable result. Here's the code in Javamail:
public static boolean deleteMessage(int j) throws Exception
{
store = session.getStore("pop3");
store.connect("localhost", "red","red");
inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
msgs[j].setFlag(Flags.Flag.DELETED, true); // set the DELETED flag
if (msgs[j].isSet(Flags.Flag.DELETED))
{
inbox.close(true);
return true;
}
return false;
}
The above method is calling every time based on how many messages selected by user to delete. If there two messages selected by user to delete, then it will be called twice. Passing those numbers as a parameter in the deleteMessage method by calling method class. But it's not doing anything, nor it's throwing any exception. What's wrong I'm doing?
Try
Message msg = inbox.getMessage(j);
msg.setFlag(Flags.Flag.DELETED, true);
if (msg.isSet(Flags.Flag.DELETED))
{
inbox.close(true);
return true;
}

Categories