Skip to main content

JavaMail 1.4.4/demo/msgshow.java

Please note these java.net forums are being decommissioned and use the new and improved forums at https://community.oracle.com/community/java.
2 replies [Last post]
josealvarezdelara
Offline
Joined: 2008-12-26

Hi,

It is resulting me really hard to understand the code of msgshow.java app.

I have done a webapp using the leading lines of code of that app but always get a "No Messages" page when I know there is at least two messages with attached files.

I want to see these messages and download the attached files.

I am using OracleXE to save the messages and when the INBOX folder is closed I have all the information in the database.

Here is my main code,

private void dumpPart(Part p,
ConcurrentMap<HTMLMessage, List<DataFile>> hashMap,
int attnum,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {

try {

HTMLMessage htmlMessage = new HTMLMessage();
List<DataFile> dfList = Collections.synchronizedList(new ArrayList<DataFile>());

if (p instanceof Message)
htmlMessage = dumpEnvelope((Message)p);

/** Dump input stream ..

InputStream is = p.getInputStream();
// If "is" is not already buffered, wrap a BufferedInputStream
// around it.
if (!(is instanceof BufferedInputStream))
is = new BufferedInputStream(is);
int c;
while ((c = is.read()) != -1)
System.out.write(c);

**/

/*
* Using isMimeType to determine the content type avoids
* fetching the actual content data until we need it.
*/
if (p.isMimeType("text/plain")) {
htmlMessage.setMessage((Object)p.getContent());
} else if (p.isMimeType("multipart/*")) {
Multipart mp = (Multipart)p.getContent();
int count = mp.getCount();
for (int i = 0; i < count; i++){
dumpPart(mp.getBodyPart(i), hashMap, ++attnum, request, response);
}
} else if (p.isMimeType("message/rfc822")) {
Part part = (Part)p.getContent();
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
part.writeTo(byteOut);
byte[] b = byteOut.toByteArray();
htmlMessage.setMessage((Object)part);
} else {
/*
* If we actually want to see the data, and it's not a
* MIME type we know, fetch it and check its Java type.
*/
Object o = p.getContent();
if (o instanceof String) {
htmlMessage.setMessage(o);
} else if (o instanceof InputStream) {
InputStream is = (InputStream)o;
int c;
StringBuffer sb = new StringBuffer();
while ((c = is.read()) != -1)
sb.append(c);
byte[] content = (sb.toString()).getBytes();
htmlMessage.setMessage((Object)content);
} else {
htmlMessage.setMessage(o);
}
}

/*
* If we're saving attachments, write out anything that
* looks like an attachment into an appropriately named
* file. Don't overwrite existing files to prevent
* mistakes.
*/

String ct = p.getContentType();
String filename = p.getFileName();

if (p.isMimeType("multipart/*")) {
String disp = p.getDisposition();
// many mailers don't include a Content-Disposition
if (disp == null || disp.equalsIgnoreCase(Part.ATTACHMENT)) {
if (filename == null)
filename = "Attachment" + attnum;

DataFile df = new DataFile();

File f = new File(filename);
if (f.exists())
// XXX - could try a series of names
throw new IOException("file exists");

df.setContentType(ct);
df.setFileName(filename);
df.setFile(f);
//((MimeBodyPart)p).saveFile(f);

dfList.add(df);
}
}

put(hashMap, htmlMessage, dfList);

} catch (Exception e) {
request.setAttribute("exception", e);
request.getRequestDispatcher("/error.jsp").forward(request, response);
}

}

And this is the method that get the messages from the INBOX folder,

private HashMap<HTMLMessage, List<DataFile>> getMessages(String host, HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

String[] myhost = {"pop3.live.com", "pop.gmail.com"};
String[] myuser = {"hotmailUser", "gmailUser"};
String password = "mypass";
int idx = 0;

if("hotmail".equals(host)) // Hotmail
idx = 0;
else if("gmail".equals(host)) // Gmail
idx = 1;

Store store = null;
Folder folder = null;

HashMap<HTMLMessage, List<DataFile>> map = new HashMap<HTMLMessage, List<DataFile>>();

try {
// Create empty properties
Properties props = new Properties();

// Get session
Session session = Session.getInstance(props, null);

// Get the store
store = session.getStore("pop3s");
store.connect(myhost[idx], myuser[idx], password);

// Get folder
folder = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);

// Get directory
Message message[] = folder.getMessages();

for (int i=0, n=message.length; i<n; i++) {

ConcurrentMap<HTMLMessage, List<DataFile>> cm = new ConcurrentHashMap<HTMLMessage, List<DataFile>>();
dumpPart(message[i], cm, 1, request, response);

List<DataFile> dfList = null;
HTMLMessage htmlMsg = null;
Set<HTMLMessage> set = cm.keySet();
for(HTMLMessage html: set){
htmlMsg = html;
dfList = cm.get(html);

if(null != htmlMsg)
map.put(htmlMsg, dfList);
}
if(map.size() == (MaxCount)) break;
}
} catch (Exception e){
request.setAttribute("exception", e);
request.getRequestDispatcher("/error.jsp").forward(request, response);
} finally {
// Close connection
try {
folder.close(false);
store.close();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

return map;
}

I know I am wrong but I do not know where.

Kind regards,
Jose

AttachmentSize
msgshow.zip4.26 KB

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
josealvarezdelara
Offline
Joined: 2008-12-26

Hi,

I have resolved all my problems. This is the method as it leaves,

private void dumpPart(
Part p,
int attnum,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {

try {

HTMLMessage htmlMessage = new HTMLMessage();
List<DataFile> dfList = new ArrayList<DataFile>();

if (p instanceof Message)
htmlMessage = dumpEnvelope((Message)p);

/** Dump input stream ..

InputStream is = p.getInputStream();
// If "is" is not already buffered, wrap a BufferedInputStream
// around it.
if (!(is instanceof BufferedInputStream))
is = new BufferedInputStream(is);
int c;
while ((c = is.read()) != -1)
System.out.write(c);

**/

/*
* Using isMimeType to determine the content type avoids
* fetching the actual content data until we need it.
*/
if (p.isMimeType("text/plain")) {
String content = (String)p.getContent();
htmlMessage.setMessage(content.getBytes());
} else if (p.isMimeType("multipart/*")) {
Multipart mp = (Multipart)p.getContent();
int count = mp.getCount();
for (int i = 0; i < count; i++){
dumpPart(mp.getBodyPart(i), ++attnum, request, response);
}
} else if (p.isMimeType("message/rfc822")) {
dumpPart((Part)p.getContent(), ++attnum, request, response);
} else {
/*
* If we actually want to see the data, and it's not a
* MIME type we know, fetch it and check its Java type.
*/
Object o = p.getContent();
if (o instanceof String) {
htmlMessage.setMessage(((String)o).getBytes());
} else if (o instanceof InputStream) {
InputStream is = (InputStream)o;
int c;
StringBuffer sb = new StringBuffer();
while ((c = is.read()) != -1)
sb.append(c);
byte[] content = (sb.toString()).getBytes();
htmlMessage.setMessage(content);
} else {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
objOut.writeObject(o);
byte[] b = byteOut.toByteArray();
htmlMessage.setMessage(b);
}
}

/*
* If we're saving attachments, write out anything that
* looks like an attachment into an appropriately named
* file. Don't overwrite existing files to prevent
* mistakes.
*/

String strCt = p.getContentType();
ContentType ct = new ContentType(strCt);
String bt = ct.getBaseType();

String filename = p.getFileName();

if (p.isMimeType("multipart/*")) {
String disp = p.getDisposition();
// many mailers don't include a Content-Disposition
if (disp == null || disp.equalsIgnoreCase(Part.ATTACHMENT)) {
if (filename == null)
filename = "Attachment" + attnum;

DataFile df = new DataFile();

File f = new File(filename);
if (f.exists())
// XXX - could try a series of names
throw new IOException("file exists");

df.setContentType(bt);
df.setFileName(filename);
df.setFile(f);
//((MimeBodyPart)p).saveFile(f);

dfList.add(df);
}
}

HashMap<HTMLMessage, List<DataFile>> hashMap = new HashMap<HTMLMessage, List<DataFile>>();
hashMap.put(htmlMessage, dfList);

save(hashMap);

} catch (Exception e) {
request.setAttribute("exception", e);
request.getRequestDispatcher("/error.jsp").forward(request, response);
}

}

public void save(HashMap<HTMLMessage, List<DataFile>> hashMap){
messagesAttachedFileManager.placeMessagesAttachedFile(hashMap);
}

being 'messagesAttachedFileManager' an ejb facade.

Everything works fine. Now I have another problem, I do not know the way to get the extension of the files,

String filename = p.getFileName();

if (disp == null || disp.equalsIgnoreCase(Part.ATTACHMENT)) {
if (filename == null)
filename = "Attachment" + attnum;

Well, I put a name to the files but without extension.

How could I know witch are those extensions?

Kind regards,
Jose

josealvarezdelara
Offline
Joined: 2008-12-26

Hi,

Yes, it is absolutely resolved.

This is the code to get the attached files,

Object content = p.getContent();

if (content instanceof Multipart) {

Multipart mp = (Multipart) content;

for (int j = 0; j < mp.getCount(); j++) {

Part part = mp.getBodyPart(j);
String disposition = part.getDisposition();

if ((disposition != null) && (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE))) {

// Check if plain
MimeBodyPart mbp = (MimeBodyPart) part;

if (!mbp.isMimeType("text/plain")) {

DataFile df = new DataFile();
df.setContentType(mbp.getContentType());

String filename = decodeName(part.getFileName());
if (filename == "unknown"){
filename = "Attachment" + attnum;
filename = setFileExtension(mbp, filename);
}
df.setFileName(filename);
String downloadDir = getServletConfig().getServletContext().getRealPath(null);
//File savedir = new File(downloadDir);
//savedir.mkdirs();
File savefile = new File(downloadDir, filename);
df.setFile(savefile);
saveFile(savefile, part);

dfList.add(df);
}

}

} // end of multipart for loop

}

being decodeName(part.getFileName()) as follows,

private String decodeName( String name ) throws Exception {
if(name == null || name.length() == 0){
return "unknown";
}
String ret = java.net.URLDecoder.decode( name, "UTF-8" );

// also check for a few other things in the string:
ret = ret.replaceAll("=\\?utf-8\\?q\\?", "");
ret = ret.replaceAll("\\?=", "");
ret = ret.replaceAll("=20", " ");

return ret;
}

For a complete version of the code see the attachment file.

Regards,

Jose