Missing start boundary Exception when reading messages with an attachment file - java

I don't know why I'm getting the following exception when reading a mail with an attachment file from mail server:
Exception in thread "main" javax.mail.MessagingException: Missing start boundary
at javax.mail.internet.MimeMultipart.parsebm<MimeMultipart.java:872)
at javax.mail.internet.MimeMultipart.parse<MimeMultipart.java:493)
at javax.mail.internet.MimeMultipart.getCount<MimeMultipart.java:240)
at GetParts.handleMultipart(GetParts.java:57)
at GetParts.main(GetParts.java:42)
The file which I'm using to read those messages is:
import java.io.*;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;
public class GetParts {
public static void main (String args[])
throws Exception {
String host = args[0];
String username = args[1];
String password = args[2];
// Get session
Properties props=new Properties();
props.put("mail.mime.multipart.ignoremissingboundaryparamete",true);
Session session = Session.getInstance(
props, null);
ContentType ct=new ContentType();
// Get the store
Store store = session.getStore("pop3");
store.connect(host, username, password);
// Get folder
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
BufferedReader reader = new BufferedReader (
new InputStreamReader(System.in));
// Get directory
Message message[] = folder.getMessages();
for (int i=0, n=message.length; i<n; i++) {
System.out.println(i + ": "
+ message[i].getFrom()[0]
+ "\t" + message[i].getSubject());
//message[i].setHeader("Content-Type","multipart/mixed");
System.out.println("Do you want to get the content? [YES to read/QUIT to end]");
String line = reader.readLine();
if ("YES".equals(line)) {
Object content = message[i].getContent();
if (content instanceof Multipart) {
handleMultipart((Multipart)content);
} else {
handlePart(message[i]);
}
} else if ("QUIT".equals(line)) {
break;
}
}
// Close connection
folder.close(false);
store.close();
}
public static void handleMultipart(Multipart multipart)
throws MessagingException, IOException {
System.out.println(multipart.getCount());
for (int i=0, n=multipart.getCount(); i<n; i++) {
handlePart(multipart.getBodyPart(i));
}
}
public static void handlePart(Part part)
throws MessagingException, IOException {
String disposition = part.getDisposition();
System.out.println("Disposition "+disposition);
String contentType = part.getContentType();
System.out.println("contentType "+contentType);
if (disposition == null) { // When just body
System.out.println("Null: " + contentType);
// Check if plain
if ((contentType.length() >= 10) &&
(contentType.toLowerCase().substring(
0, 10).equals("text/plain"))) {
part.writeTo(System.out);
} else { // Don't think this will happen
System.out.println("Other body: " + contentType);
part.writeTo(System.out);
}
} else if (disposition.equalsIgnoreCase(Part.ATTACHMENT)) {
System.out.println("Attachment: " + part.getFileName() +
" : " + contentType);
saveFile(part.getFileName(), part.getInputStream());
} else if (disposition.equalsIgnoreCase(Part.INLINE)) {
System.out.println("Inline: " +
part.getFileName() +
" : " + contentType);
saveFile(part.getFileName(), part.getInputStream());
} else { // Should never happen
System.out.println("Other: " + disposition);
}
}
public static void saveFile(String filename,
InputStream input) throws IOException {
if (filename == null) {
filename = File.createTempFile("xx", ".out").getName();
}
// Do no overwrite existing file
File file = new File(filename);
for (int i=0; file.exists(); i++) {
file = new File(filename+i);
}
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
BufferedInputStream bis = new BufferedInputStream(input);
int aByte;
while ((aByte = bis.read()) != -1) {
bos.write(aByte);
}
bos.flush();
bos.close();
bis.close();
}
}

I've just had the same problem. The boundary is specified within the Multipart Content-Type. You can find further information in this source. You can also watch the one of your current Message using the getContentType() function. In my case I obtained this result:
multipart/mixed; boundary=--boundary_25_2d74d02b-d0d6-4f28-a311-4d1b7d107417
So the getCount() function uses this boundary to separate all the parts that compose the multiple part. Looks like there could be cases in which this boundary is corrupted.
The mail.mime.multipart.ignoreexistingboundaryparameter System property may be set to true to cause any boundary to be ignored and instead search for a boundary line in the message as with mail.mime.multipart.ignoremissingboundaryparameter.
I followed this instructions and everything works all right. I added the code below:
System.setProperty("mail.mime.multipart.ignoreexistingboundaryparameter", "true");
Hope it helps!

try to set mode on the multipartEntityBuilder
ex:
multipartEntityBuilder.setMode(HttpMultipartMode.RFC6532);

Related

breaking the lines while chunking into multiple files

I am dividing my file into chunks but only problem i am facing is,
i have .srt file, but while doing chunks, it's cutting the characters i.e in first .srt file it's like 00:26:20,230 --> . in next file it continuing the next time stamp 00:27:40,343.
I need to check the timestamp to be complete and then next full subtitle sentence too. i.e if it's cutting the subtitle timesstamp or dialogue in in file, that tect to be append to next file. Please suggest me how can i achieve.
I am trying like below,
String FilePath = "/Users/meh/Desktop/escapeplan.srt";
FileInputStream fin = new FileInputStream(FilePath);
System.out.println("size: " +fin.getChannel().size());
long abc = 0l;
abc = (fin.getChannel().size())/3;
System.out.println("6: " +abc);
System.out.println("abc: " +abc);
//FilePath = args[1];
File filename = new File(FilePath);
long splitFileSize = 0,bytefileSize=0;
if (filename.exists()) {
try {
//bytefileSize = Long.parseLong(args[2]);
splitFileSize = abc;
Splitme spObj = new Splitme();
spObj.split(FilePath, (long) splitFileSize);
spObj = null;
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println("File Not Found....");
}
public void split(String FilePath, long splitlen) {
long leninfile = 0, leng = 0;
int count = 1, data;
try {
File filename = new File(FilePath);
InputStream infile = new BufferedInputStream(new FileInputStream(filename));
data = infile.read();
System.out.println("data");
System.out.println(data);
while (data != -1) {
filename = new File("/Users/meh/Documents/srt" + count + ".srt");
//RandomAccessFile outfile = new RandomAccessFile(filename, "rw");
OutputStream outfile = new BufferedOutputStream(new FileOutputStream(filename));
while (data != -1 && leng < splitlen) {
outfile.write(data);
leng++;
data = infile.read();
}
leninfile += leng;
leng = 0;
outfile.close();
changeTimeStamp(filename, count);
count++;
}
} catch (Exception e) {
e.printStackTrace();
}
}
i am trying to check the time stamp is in correct format or not. Then i need to check next line to be a dialogue and then the next line to be empty line. then it can stop chunk or else it should append the text from the previous chunk to next chunk file in the beginning of line . so that it may get in correct format.
I tried checking the format like,
while ((strLine = br.readLine()) != null) {
String[] atoms = strLine.split(" --> ");
if (atoms.length == 1) {
out.write(strLine + "\n");
} else {
String startTS = atoms[0];
String endTS = atoms[1];
System.out.print("sri atmos start" + startTS);
System.out.print("sri atmos end" + endTS);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss,SSS");
sdf.setLenient(false);
try
{
sdf.parse(startTS);
sdf.parse(endTS);
System.out.println("Valid time");
System.out.println("File path" + srcFileNm);
}
catch(Exception e) {
System.out.println("Invalid time");
System.out.println("Exception start" + startTS);
System.out.println("Exception end" + endTS);
}
}
some screens of my output chunks,
Help me how can i make this possible.
I think you should change approach, and fully use basic I/O methods. I tried to encapsulate logic in a small class, that produces a triple with id, msecs and a list of subtitles (if I'm not wrong, you can have more than a line). Then I leaved the remainder externally. Chunker is a class that reads a triple (class Three) from file, so that you can manage it and write it somewhere.
This is just a "quick&dirty" idea that you can refine, but it should work.
package org.norsam.stackoverflow;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Chunker
{
BufferedReader r;
int chunk = 0;
File dir;
public Chunker(File dir, String filename) throws IOException
{
File f = new File(dir, filename);
this.dir = dir;
this.r = new BufferedReader(new FileReader(f));
}
public Three readThree() throws IOException
{
Integer id = Integer.parseInt(r.readLine());
String msecs = r.readLine();
String s = null;
List<String> srt = new ArrayList<>();
while (!(s = r.readLine().trim()).isEmpty()) {
srt.add(s);
}
return new Three(id, msecs, srt);
}
class Three
{
Integer id;
String msecs;
List<String> srts;
Three(Integer id, String msecs, List<String> srts)
{
this.id = id;
this.msecs = msecs;
this.srts = srts;
}
Three doSomething() {
// here you can do something with your data,
// e.g. split msecs on "-->" and check times
return this;
}
void write(BufferedWriter r) throws IOException
{
r.write(id);
r.newLine();
r.write(msecs);
r.newLine();
for (String s : srts) {
r.write(s);
r.newLine();
}
r.newLine();
}
}
public static void main(String[] args) throws IOException
{
String baseDir = "/dir/where/resides/srt";
String filename = "filename.srt";
int elemPerChunk = 50;
int fileNum = 0;
File dir = new File(baseDir);
Chunker chunker = new Chunker(dir, filename);
boolean completed = false;
while (!completed) {
int srtCount = 0;
File f = new File(baseDir, "ch." + (fileNum++) + "." + filename);
BufferedWriter w = new BufferedWriter(new FileWriter(f));
try {
while (srtCount++ < elemPerChunk) {
chunker.readThree().doSomething().write(w);
}
} catch (NullPointerException e) {
completed = true;
}
w.close();
}
}
}

PrintWriter.println - works - but not print?

i have a really suspicious case here, envolving a simple method which is supposed to write into a .txt file.
public void extractCoNLL(int n, String outputFile) throws IOException {
String msg;
PrintWriter pr = new PrintWriter(outputFile);
FileInputStream fConlliN = new FileInputStream(this.txt_CoNLL_in);
BufferedReader readBufferData = new BufferedReader(new InputStreamReader(fConlliN));
try {
while ((msg = readBufferData.readLine()) != null) {
String aMsg[] = msg.split("\\s+");
if (!msg.startsWith("#")) {
//pr.println(msg);
if (aMsg.length >= n) {
pr.print(aMsg[n] + "_"); // DOES NOT WORK
pr.println(aMsg[n] + "_"); // WORKS ?????
System.out.println(aMsg[4] + aMsg.length);
} else {
pr.println();
}
}
}
this.txt_CoNLL = out_Extracted_txt_CoNLL;
} catch (Exception e) {
System.err.println("Error Exception: " + e.getMessage());
}
}
Also, why is it not possible for me to add a simple " " -space but i have to be forced to use "_" to seperate the words.
Very grateful for your Help.
Thank you in advance!

Speed up email retrieval with JavaMail

Currently my code accesses my Gmail inbox with IMAP (imaps) and JavaMail, for the purpose of reading emails sent to myself from newest to oldest, identifying which ones have attachments in the .zip or .xap format. If found, the email's subject is displayed and asks if I want to download the attachment.
If I click no, it continues searching. If I click yes, it calls the createFolder method to create a directory, saves the attachment there, and then extracts it.
Problem: The most recent email in my inbox has a .zip file so it is quickly found, but if I click "No" it takes upwards of 20 seconds to find the next email containing a zip/xap for 2 reasons: (1) There are 20+ emails more recent (2) There are 2 emails more recent containing attachments BUT NOT zip/xap.
I'm guessing this is due to the recursion that's occuring to isolate attachments before identifying their format, or some other redundant code/method? I've read here and here that a Fetch Profile can help, instead of contacting the server unnecessarily.
I'm hoping to decrease the delay substantially. Is Fetch/Envelope the way to go? Is my code a tangled mess, or can you share a sample solution? Thank you!
Full Code:
public class ReceiveMailImap {
public ReceiveMailImap() {}
public static void doit() throws MessagingException, IOException {
Folder inbox = null;
Store store = null;
try {
Properties props = System.getProperties();
Session session = Session.getDefaultInstance(props, null);
//session.setDebug(true);
store = session.getStore("imaps");
store.connect("imap.gmail.com", "myAccount#gmail.com", "myPassword");
inbox = store.getFolder("Inbox");
inbox.open(Folder.READ_WRITE);
Message messages[] = inbox.getMessages();
// Loop newest to oldest
for (int i = messages.length - 1; i >= 0; i--) {
Message msg = messages[i];
//If current msg has no attachment, skip.
if (!hasAttachments(msg)) {
continue;
}
String from = "Sender Unknown";
if (msg.getReplyTo().length >= 1) {
from = msg.getReplyTo()[0].toString();
} else if (msg.getFrom().length >= 1) {
from = msg.getFrom()[0].toString();
}
subject = msg.getSubject();
if (from.contains("myAccount#gmail.com")) {
//Get My Documents
subject = subject.replaceAll("[^a-zA-Z0-9.-]", "_");
//Call Save Attachment -->>
saveAttachment(msg.getContent());
msg.setFlag(Flags.Flag.SEEN, true);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (inbox != null) {
inbox.close(true);
}
if (store != null) {
store.close();
}
}
}
public static boolean hasAttachments(Message msg) throws MessagingException, IOException {
if (msg.isMimeType("multipart/mixed")) {
Multipart mp = (Multipart) msg.getContent();
if (mp.getCount() > 1) return true;
}
return false;
}
public static void saveAttachment(Object content)
throws IOException, MessagingException {
OutputStream out = null;
InputStream in = null;
try {
if (content instanceof Multipart) {
Multipart multi = ((Multipart) content);
int parts = multi.getCount();
for (int j = 0; j < parts; ++j) {
MimeBodyPart part = (MimeBodyPart) multi.getBodyPart(j);
if (part.getContent() instanceof Multipart) {
// part-within-a-part, do some recursion...
saveAttachment(part.getContent());
} else {
int allow = 0;
if (part.isMimeType("application/x-silverlight-app")) {
extension = "xap";
allow = 1;
} else {
if (part.isMimeType("application/zip")) {
extension = "zip";
allow = 1;
}
}
if (allow == 1) {
int dialogResult = JOptionPane.showConfirmDialog(null, "The most recent file is: " + subject + " Would you like to download this file?", "Question", 0);
if (dialogResult == JOptionPane.YES_OPTION) {
savePath = createFolder(subject) + "\\" + subject + "." + extension;
} else {
continue;
}
out = new FileOutputStream(new File(savePath)); in = part.getInputStream();
int k;
while ((k = in .read()) != -1) {
out.write(k);
}
//Unzip
savePath = savePath.toString();
Unzip unzipFile = new Unzip();
unzipFile.UnZipper(dir, savePath);
} else {
continue;
}
}
}
}
} finally {
if ( in != null) { in .close();
}
if (out != null) {
out.flush();
out.close();
}
}
}
public static File createFolder(String subject) {
JFileChooser fr = new JFileChooser();
FileSystemView myDocs = fr.getFileSystemView();
String myDocuments = myDocs.getDefaultDirectory().toString();
dir = new File(myDocuments + "\\" + subject);
savePathNoExtension = dir.toString();
dir.mkdir();
return dir;
}
public static void main(String args[]) throws Exception {
ReceiveMailImap.doit();
}
}
A FetchProfile allows you to prefetch some of the message information "in bulk". This prefetched information is then used later when you access the corresponding fields of the Message objects. You probably want to use FetchProfile.Item.CONTENT_INFO and FetchProfile.Item.ENVELOPE. Other than that, your code looks fine.

Working with BufferedOutputStream

Im using BufferedOutputStream for writing in a file ,it writes list of files and directories in th specified driver, heres the code:
import java.io.File;
import java.nio.file.*;
import java.io.*;
import static java.nio.file.StandardOpenOption.*;
public class DirectoryReader {
static int spc_count=-1;
static void Process(File aFile)
{
String s;
Path file =
Paths.get("C:\\Java\\Files1.txt");
try
{
OutputStream output= new
BufferedOutputStream(Files.newOutputStream(file,CREATE));
spc_count++;
String spcs = "";
byte [] data= new byte [2048 * 2048];
for (int i = 0; i < spc_count; i++)
spcs += " ";
if(aFile.isFile())
{
System.out.println(spcs + "[FILE] " + aFile.getPath());
s=aFile.getPath();
System.out.println(" " + s);
data = s.getBytes();
output.write(data);
output.write(13);
output.write(10);
output.flush();
}
else if (aFile.isDirectory()) {
{
System.out.println(spcs + "[DIR] " + aFile.getPath());
s=aFile.getPath();
data = s.getBytes();
output.write(data);
output.write(13);
output.write(10);
output.flush();
}
File[] listOfFiles = aFile.listFiles();
if(listOfFiles!=null) {
for (int i = 0; i < listOfFiles.length; i++)
Process(listOfFiles[i]);
} else {
System.out.println(spcs + " [ACCESS DENIED]");
}
}
output.close();
spc_count--;
}
catch(Exception e)
{
System.out.println("Message: " + e);
}
}
public static void main(String[] args) {
String nam = "D:\\Notes";
File aFile = new File(nam);
Process(aFile);
}
}
but when I go to see the file , I only find the last file written and sometimes I find mixed words .
You are using recurrent calls to your Process method. This method is creating NEW FILE upon execution, so previous content is simply overriden. I would suggest, that you should create output stream, and pass it as argument to every call Process message. This way, you will provide single output stream for storing data. And the problem will be gone.

Uploading Image From Java Desktop App to Server

I am using the following code on the client side to upload to the server
public class UploaderExample{
private static final String Boundary = "--7d021a37605f0";
public void upload(URL url, List<File> files) throws Exception
{
HttpURLConnection theUrlConnection = (HttpURLConnection) url.openConnection();
theUrlConnection.setDoOutput(true);
theUrlConnection.setDoInput(true);
theUrlConnection.setUseCaches(false);
theUrlConnection.setChunkedStreamingMode(1024);
theUrlConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary="
+ Boundary);
DataOutputStream httpOut = new DataOutputStream(theUrlConnection.getOutputStream());
for (int i = 0; i < files.size(); i++)
{
File f = files.get(i);
String str = "--" + Boundary + "\r\n"
+ "Content-Disposition: form-data;name=\"file" + i + "\"; filename=\"" + f.getName() + "\"\r\n"
+ "Content-Type: image/png\r\n"
+ "\r\n";
httpOut.write(str.getBytes());
FileInputStream uploadFileReader = new FileInputStream(f);
int numBytesToRead = 1024;
int availableBytesToRead;
while ((availableBytesToRead = uploadFileReader.available()) > 0)
{
byte[] bufferBytesRead;
bufferBytesRead = availableBytesToRead >= numBytesToRead ? new byte[numBytesToRead]
: new byte[availableBytesToRead];
uploadFileReader.read(bufferBytesRead);
httpOut.write(bufferBytesRead);
httpOut.flush();
}
httpOut.write(("--" + Boundary + "--\r\n").getBytes());
}
httpOut.write(("--" + Boundary + "--\r\n").getBytes());
httpOut.flush();
httpOut.close();
// read & parse the response
InputStream is = theUrlConnection.getInputStream();
StringBuilder response = new StringBuilder();
byte[] respBuffer = new byte[4096];
while (is.read(respBuffer) >= 0)
{
response.append(new String(respBuffer).trim());
}
is.close();
System.out.println(response.toString());
}
public static void main(String[] args) throws Exception
{
List<File> list = new ArrayList<File>();
list.add(new File("C:\\square.png"));
list.add(new File("C:\\narrow.png"));
UploaderExample uploader = new UploaderExample();
uploader.upload(new URL("http://systemout.com/upload.php"), list);
}
}
I have tried writing the servlet that receives the image file and saves it to a folder on the server....but have failed miserably...This is part of an academic project i need to submit as part of my degree....Please Help!!!
I want help ...can someone guide me on how the servlet will be written....
I tried the following:
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
InputStream input = null;
OutputStream output = null;
try {
input = request.getInputStream();
output = new FileOutputStream("C:\\temp\\file.png");
byte[] buffer = new byte[10240];
for (int length = 0; (length = input.read(buffer)) > 0 ; ) {
output.write(buffer, 0, length);
}
}
catch(Exception e){
out.println(e.getMessage());
}
finally {
if (output != null) {
output.close();
}
if (input != null) {
input.close();
}
}
out.println("Success");
}
catch(Exception e){
out.println(e.getMessage());
}
finally {
out.close();
}
}
I went ahead and tried the fileupload from apache.org....and wrote the following servlet code:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println(1);
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the request
List /* FileItem */ items = upload.parseRequest(request);
// Process the uploaded items
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {
//processFormField(item);
} else {
//processUploadedFile(item);
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();
//write to file
File uploadedFile = new File("C:\\temp\\image.png");
item.write(uploadedFile);
out.println("Sucess!");
}
}
} else {
out.println("Invalid Content!");
}
} catch (Exception e) {
out.println(e.getMessage());
} finally {
out.close();
}
}
However i am still confused on how to write the multipart code on the client side...the one i posted above is not working with my servlet implementation.....help please....some links where i can learn writing posting multipart form from java desktop app would be useful
So here's my recommendation: don't write this code yourself! Use http://commons.apache.org/fileupload/ instead. It will save you a lot of headaches, and you'll be up and running quite quickly. I'm pretty sure that problem is that the InputStream contains the multi-part boundaries, and is thus not a valid image.
Here's another observation: since you're not doing any transformations on the image, there's no need to read and write the image bytes using ImageIO. You're better off writing the bytes straight from the InputStream to the file.

Categories