Using multiple threads to download files using JSch - java

I am trying to download multiple files from a remote server using multiple threads. However when I am using multiple threads I get
java.lang.IOException : Pipes closed.
The same code works fine when i am using exactly one thread.
Is it not possible to download multiple files simultaneously from the same remote server using JSch?
SftpTest.java
public class SftpTest {
private static List<SftpAccessor> accessorList = new ArrayList<SftpAccessor>();
private static List<Payload> files = new ArrayList<Payload>();
private static ExecutorService writerThreadPool = Executors.newFixedThreadPool(10);
public static void main(String args[]) throws JSchException, InterruptedException {
SSH srcServer = new SSH();
srcServer.setHostname("10.22.65.140");
srcServer.setKey("D:\\jars\\dmwvmcol01.ec2user.pem");
srcServer.setPort("22");
srcServer.setUsername("ec2-user");
SftpAccessor acc = new SftpAccessor(srcServer);
accessorList.add(acc);
files.addAll(acc.ls("/data/test/src", false, "*", 1));
for (Payload file : files) {
writerThreadPool.submit(new LocalWriterThread(file));
}
writerThreadPool.shutdown();
writerThreadPool.awaitTermination(20, TimeUnit.MINUTES);
}}
LocalWriterThread.java
public class LocalWriterThread implements Callable<String> {
private Payload payload;
public LocalWriterThread(Payload payload) {
this.payload = payload;
}
public String call() throws Exception {
String dest = "D:\\output\\jobsystemnew";
System.out.println(payload.getFilename());
File file = new File(dest + "/" + payload.getFilename());
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
copy(payload.getInputStream(), fos);
payload.setInputStream(null);
return "";
}
private void copy(InputStream is, OutputStream os) throws IOException {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
System.out.println("Started Copying file : " + payload.getFilename());
bis = new BufferedInputStream(is);
bos = new BufferedOutputStream(os);
byte[] buffer = new byte[1024];
while (bis.read(buffer) != -1) {
bos.write(buffer);
}
bos.flush();
System.out.println("Finished Copying file : " + payload.getFilename());
}
finally {
System.out.println("Closing input stream for " + payload.getFilename());
bis.close();
bos.close();
/*
* try { if (is != null) { is.close(); } } catch (Exception e) { System.out.println(" " + e + " : " + e.getMessage() + " unable to close input stream : " + payload.getFilename());
* e.printStackTrace(); }
*/
/*
* try { if (os != null) { os.close(); } } catch (Exception e) { System.out.println(" " + e + " : " + e.getMessage() + " unable to close output stream : " + payload.getFilename());
* e.printStackTrace(); }
*/
}
}}
SSH.java
public class SSH {
String hostname;
String port;
String username;
String key;
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
} }
SftpAccessor.java
public class SftpAccessor {
private JSch jsch = new JSch();
private ChannelSftp channelSftp = null;
private Session session = null;
String errorMsg = null;
public SftpAccessor(SSH ssh) throws JSchException {
jsch.addIdentity(ssh.getKey());
session = jsch.getSession(ssh.getUsername(), ssh.getHostname(), Integer.parseInt(ssh.getPort()));
session.setHostKeyAlias(ssh.getKey());
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
channelSftp = (ChannelSftp) session.openChannel("sftp");
channelSftp.connect();
}
public List<Payload> ls(String directory, boolean recursive, String filemask, int delayMinutes) {
List<Payload> files = new ArrayList<Payload>();
try {
channelSftp.cd(directory);
#SuppressWarnings("unchecked")
Vector<ChannelSftp.LsEntry> entries = channelSftp.ls(filemask);
for (ChannelSftp.LsEntry entry : entries) {
try {
if (entry.getAttrs().isDir()) {
if (recursive) {
List<Payload> filesToAdd = ls(directory + "/" + entry.getFilename(), recursive, filemask, delayMinutes);
files.addAll(filesToAdd);
}
}
else {
Date lastmodified = new Date(entry.getAttrs().getMTime() * 1000L);
Date currdate = new Date(new Date().getTime() - (delayMinutes * 60 * 1000L));
if (lastmodified.before(currdate)) {
String filename = entry.getFilename();
entry.getAttrs().getMTime();
Payload file = new Payload();
System.out.println("Getting input Stream for " + directory + "/" + filename);
file.setInputStream(channelSftp.get(directory + "/" + filename));
file.setFilename(filename);
file.setLastModified(lastmodified);
files.add(file);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
catch (SftpException e) {
}
return files;
}}
Payload.java
public class Payload {
private String filename;
private InputStream inputStream;
private Date lastModified;
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public Date getLastModified() {
return lastModified;
}
public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}}

JSch is not thread-safe. Even if it were, there's hardly any performance advantage in using parallel downloads over a single SSH session. It would be as slow as serial downloads. Moreover, you may hit server-side limit of concurrent file handles.
You should open a separate session for each thread/download.

Related

UDP Socket: java.net.SocketException: socket closed

MessageCreator: Encapsulate and resolve ports and device unique identifiers.
public class MessageCreator {
private static final String HEADER_PORT = "to port:";
private static final String HEADER_SN = "My sn:";
public static String buildWithPort(int port) {
return HEADER_PORT + port;
}
public static int parsePort(String data) {
if (data.startsWith(HEADER_PORT)) {
return Integer.parseInt(data.substring(HEADER_PORT.length()));
}
return -1;
}
public static String buildWithSn(String sn) {
return HEADER_SN + sn;
}
public static String parseSn(String data) {
if (data.startsWith(HEADER_SN)) {
return data.substring(HEADER_SN.length());
}
return null;
}
}
UdpProvider: Loop to listen to a specific port, then parse the received data, determine whether the data conforms to the predetermined format, get the sender's response port from it, and respond with the uniquely identified UUID value to the UDP searcher.
public class UdpProvider {
public static void main(String[] args) throws IOException {
String sn = UUID.randomUUID().toString();
Provider provider = new Provider(sn);
provider.start();
// Warning: Result of 'InputStream.read()' is ignored
System.in.read();
provider.exit();
}
private static class Provider extends Thread {
private DatagramSocket ds = null;
private boolean done = false;
private final String sn;
public Provider(String sn) {
super();
this.sn = sn;
}
#Override
public void run() {
super.run();
try {
ds = new DatagramSocket(20000);
while (!done) {
final byte[] buf = new byte[512];
DatagramPacket receivePak = new DatagramPacket(buf, buf.length);
ds.receive(receivePak);
String ip = receivePak.getAddress().getHostAddress();
int port = receivePak.getPort();
byte[] receivePakData = receivePak.getData();
String receiveData = new String(receivePakData, 0, /*receivePakData.length*/receivePak.getLength());
System.out.println("received from -> ip: " + ip + ", port: " + port + ", data: " + receiveData);
int responsePort = MessageCreator.parsePort(receiveData.trim());
if (responsePort != -1) {
String responseData = MessageCreator.buildWithSn(sn);
byte[] bytes = responseData.getBytes(StandardCharsets.UTF_8);
DatagramPacket responsePak = new DatagramPacket(bytes, bytes.length,
/*InetAddress.getLocalHost()*/
receivePak.getAddress(),
responsePort);
ds.send(responsePak);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close();
}
}
public void exit() {
done = true;
close();
}
public void close() {
if (ds != null) {
ds.close();
ds = null;
}
}
}
}
UdpSearcher: Listening to a specific port and sending a LAN broadcast, sending a broadcast sets the listening port in the data, so you need to turn on listening first to finish before you can send a broadcast, and once you receive the response data, you can parse the device information
public class UdpSearcher {
private static final int LISTENER_PORT = 30000;
public static void main(String[] args) throws IOException, InterruptedException {
Listener listener = listen();
sendBroadcast();
// Warning: Result of 'InputStream.read()' is ignored
System.in.read();
List<Device> deviceList = listener.getDevicesAndClose();
for (Device device : deviceList) {
System.out.println(device);
}
}
public static void sendBroadcast() throws IOException {
DatagramSocket ds = new DatagramSocket();
String sendData = MessageCreator.buildWithPort(LISTENER_PORT);
byte[] sendDataBytes = sendData.getBytes(StandardCharsets.UTF_8);
DatagramPacket sendPak = new DatagramPacket(sendDataBytes, sendDataBytes.length);
sendPak.setAddress(InetAddress.getByName("255.255.255.255"));
sendPak.setPort(20000);
ds.send(sendPak);
ds.close();
}
public static Listener listen() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
Listener listener = new Listener(LISTENER_PORT, countDownLatch);
listener.start();
countDownLatch.await();
return listener;
}
private static class Listener extends Thread {
private final int listenPort;
private DatagramSocket ds = null;
private boolean done = false;
private final CountDownLatch countDownLatch;
private List<Device> devices = new ArrayList<>();
public Listener(int listenPort, CountDownLatch countDownLatch) {
super();
this.listenPort = listenPort;
this.countDownLatch = countDownLatch;
}
#Override
public void run() {
super.run();
countDownLatch.countDown();
try {
ds = new DatagramSocket(listenPort);
while (!done) {
final byte[] buf = new byte[512];
DatagramPacket receivePak = new DatagramPacket(buf, buf.length);
ds.receive(receivePak);
String ip = receivePak.getAddress().getHostAddress();
int port = receivePak.getPort();
byte[] data = receivePak.getData();
String receiveData = new String(data, 0, /*data.length*/receivePak.getLength());
String sn = MessageCreator.parseSn(receiveData);
System.out.println("received from -> ip: " + ip + ", port: " + port + ", data: " + receiveData);
if (sn != null) {
Device device = new Device(ip, port, sn);
devices.add(device);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close();
}
}
public void close() {
if (ds != null) {
ds.close();
ds = null;
}
}
public List<Device> getDevicesAndClose() {
done = true;
close();
return devices;
}
}
private static class Device {
private String ip;
private int port;
private String sn;
public Device(String ip, int port, String sn) {
this.ip = ip;
this.port = port;
this.sn = sn;
}
#Override
public String toString() {
return "Device{" +
"ip='" + ip + '\'' +
", port=" + port +
", sn='" + sn + '\'' +
'}';
}
}
}
UdpProvider and UdpSearcher worked fine and printed corrresponding data until I input a char sequence from keyboard follwed by pressing Enter key on each console window, both threw an exception on this line ds.receive(receivePak); :

ObjectInput/OutputStream seems to not serialize/Deserialize

I'm writing a fairly simple program, which needs to save some simple data between runs. This data is defined by UserData, outlined below:
public class UserData implements Serializable {
/**
*
*/
private static final long serialVersionUID = -3542558265070011448L;
public static ArrayList<String> projectList;
public static ArrayList<Bill> billList;
public static String userName;
public static String userEmail;
public UserData() {
}
public UserData(String name, String email) {
super();
userName = name;
userEmail = email;
projectList = new ArrayList<String>();
billList = new ArrayList<Bill>();
}
public String getUserName() {
return userName;
}
public String getUserEmail() {
return userEmail;
}
public ArrayList<Bill> getBillList() {
return billList;
}
public ArrayList<String> getProjectList() {
return projectList;
}
public void setBillList(Bill theBill) {
billList.add(theBill);
}
public void setProjectList(String projectName) {
projectList.add(projectName);
}
}
I Then have a class which handles serializing/deserializing of this data and it's instance to a file, with the various calls done directly or indirectly by events in a separate Gui Class. This is it:
public class FileHandler implements Serializable {
/**
*
*/
private static final long serialVersionUID = 473118590700911358L;
private static JFileChooser fileChooser;
public UserData myUserData;
public FileHandler() throws ClassNotFoundException, IOException {
fileChooser = new JFileChooser();
initData();
}
public FileHandler(UserData newUser) {
fileChooser = new JFileChooser();
myUserData = newUser;
System.out.println("Entered User: " + myUserData.getUserName());
System.out.println("Entered User: " + myUserData.getUserEmail());
}
private void createProgramData() throws FileNotFoundException, IOException {
FileOutputStream fileOut = new FileOutputStream("data\\ProgramData.diy");
ObjectOutputStream encoderp = new ObjectOutputStream(fileOut);
System.out.println("createProgramData: " + myUserData.getUserName());
System.out.println("createProgramData: "+ myUserData.getUserEmail());
encoderp.writeObject(myUserData);
encoderp.close();
fileOut.close();
}
public void exportData() throws FileNotFoundException, IOException {
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
final int selectedFile = fileChooser.showOpenDialog(null);
ObjectOutputStream encodere = null;
if (selectedFile == JFileChooser.APPROVE_OPTION) {
final File selectedPath = fileChooser.getSelectedFile();
FileOutputStream fileOut = new FileOutputStream(selectedPath + "\\UserData.diy");
encodere = new ObjectOutputStream(fileOut);
System.out.println("Writing Data: " + myUserData.getUserName());
System.out.println("Writing Data: " + myUserData.getUserEmail());
encodere.writeObject(myUserData);
encodere.close();
fileOut.close();
}
}
public void importData() throws ClassNotFoundException, IOException {
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
final int selectedFile = fileChooser.showSaveDialog(null);
ObjectInputStream decoderim = null;
if (selectedFile == JFileChooser.APPROVE_OPTION) {
final File selectedPath = fileChooser.getSelectedFile();
FileInputStream fileIn = new FileInputStream(selectedPath);
decoderim = new ObjectInputStream(fileIn);
myUserData = (UserData)decoderim.readObject();
decoderim.close();
fileIn.close();
System.out.println("importing Data: " + myUserData.getUserEmail());
System.out.println("importing Data: " + myUserData.getUserName());
}
}
private void initData() throws IOException, ClassNotFoundException {
FileInputStream fileIn = new FileInputStream("data\\ProgramData.diy");
ObjectInputStream decoderi = new ObjectInputStream(fileIn);
myUserData = (UserData)decoderi.readObject();
decoderi.close();
fileIn.close();
System.out.println("initializing Data: " + myUserData.getUserName());
System.out.println("Initializing Data: " + myUserData.getUserEmail());
}
public UserData getUserData() {
return myUserData;
}
A problem I'm having with the ObjectInputStream and possibly ObjectOutputStream seems to be that when I serialize UserData, exit my program, and then re-enter and try to import that file, the instance of UserData remains unchanged. I can't seem to figure out what I'm missing. Even pointing out something I've overlooked helps.
UserData only has static fields, and static fields aren't serialized. From the look of your code they should all be instance members. Don't make anything static unless you know exactly why you are doing so.

Properties File Java

I want to use a pre-configured properties File, load it, and after that, add a line under the already present line from the default config.properties.
I have a read() function that will read/load my default Properties file and I have a write() function that will add String key = "hey"; String value = "ho";
But when I launch read() and write() and when i look in the new config.properties I only see
hey=ho
In my default config.properties i got
ha=hi
hu=hu
But I want in my new config :
ha=hi
hu=hu
hey=ho
My code:
Properties prop = new Properties();
public static PropertiesIParse instance;
public PropertiesIParse() {
instance = this;
}
public PropertiesIParse getInstance() {
return instance;
}
public Properties getProp() {
return prop;
}
public void read() {
InputStream input = null;
try {
String filename = "/config.properties";
input = PropertiesIParse.class.getResourceAsStream(filename);
if (input == null) {
System.out.println("Sorry, unable to find " + filename);
return;
}
getProp().load(input);
Enumeration<?> e = getProp().propertyNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value = getProp().getProperty(key);
System.out.println("KeyKey : " + key + ", Value : " + value);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void write() {
String filename = "config.properties";
FileOutputStream out;
//prop = new Properties();
String key = "hey";
String value = "ho";
try {
out = new FileOutputStream(filename, true);
getProp().setProperty(key, value);
getProp().store(out, "--type--"); // <---- variable pour dire YYYY MM DD etc.
out.close();
} catch (IOException i) {
System.out.println("Probleme avec l'écriture dans le fichier Property." + i.getMessage());
i.printStackTrace();
}
}
So, in my Main method:
new PropertiesIParse().getInstance().read();
new PropertiesIParse().getInstance().write();
EDIT
i change what you say but i got the same thing ... a new config.properties with only my prop.store(key,value) in it
Properties prop = new Properties();
static PropertiesIParse instance;
private PropertiesIParse() {
instance = this;
}
public static PropertiesIParse getInstance() {
if (instance== null) {
instance = new PropertiesIParse();
}
return instance;
}
public void read() {
InputStream input = null;
Properties prop = new Properties();
try {
String filename = "config.properties";
input = PropertiesIParse.class.getResourceAsStream(filename);
if (input == null) {
System.out.println("Sorry, unable to find " + filename);
return;
}
prop.load(input);
Enumeration<?> e = prop.propertyNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value =prop.getProperty(key);
System.out.println("Key : " + key + ", Value : " + value);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void write(String key, String value) {
Properties prop = new Properties();
String filename = "./config.properties";
String comment="";
FileOutputStream out;
try {
out = new FileOutputStream(filename, true);
prop.setProperty(key, value);
prop.store(out, "-"+key+"-"+comment);
out.close();
} catch (IOException i) {
System.out.println("Probleme avec l'écriture dans le fichier Property." + i.getMessage());
i.printStackTrace();
}
}
My Main
PropertiesIParse.getInstance().read();
PropertiesIParse.getInstance().write(new String("ok"),new String("iiiii"));
And i only got ok=iiiii in it ... i surely miss something there, thanks for your help
Your singleton is broken as you use a public constructor. Each time you call -
new PropertiesIParse()
there a new instance of Properties will be created which will be empty.
Make the constructor private and change the getInstance() as follows
public PropertiesIParse getInstance() {
if (instance== null) {
instance = new PropertiesIParse();
}
return instance;
}
Then use it without using new:
PropertiesIParse.getInstance().read();
PropertiesIParse.getInstance().write();

Java: How to download a file via imap:// protocol?

How can I download a file given the following URL with Java-SE-7:
imap://georg#imap.acme.com:143/fetch%3EUID%3E/INBOX%3E18678?fileName=testmail.eml
Any help highly appreciated - thank you in advance.
Here's my basic solution. The following code needs Apache Commons I/O 2.4 which can be downloaded here:
public class ImapMessage {
private String authority;
private String protocol;
private String host;
private int port;
private String username;
private String password;
private String foldername;
private long msgid;
private String filename;
private Message message;
public ImapMessage(String url) throws IOException, MessagingException {
parseURL(decodeURL(url));
}
#Override
public String toString() {
return "protocol: "+protocol+"\n"+
"host: "+host+"\n"+
"port: "+port+"\n"+
"username: "+username+"\n"+
"password: "+password+"\n"+
"folder: "+foldername+"\n"+
"msgid: "+msgid+"\n"+
"filename: "+filename;
}
private String decodeURL(String url) throws IOException {
if(url!=null && !url.isEmpty()) {
url = StringUtils.replace(url, "%3E", ">");
url = StringUtils.replace(url, "%20", " ");
return url;
} else {
throw new IOException("The given URL is empty or invalid.");
}
}
private void parseURL(String url) throws IOException, MalformedURLException {
if(url!=null && !url.isEmpty()) {
//<editor-fold defaultstate="collapsed" desc="Parse Protocol">
if(url.startsWith("imaps")) {
url = StringUtils.replace(url, "imaps", "http", 1);
protocol = "imaps";
} else if(url.startsWith("imap")) {
url = StringUtils.replace(url, "imap", "http", 1);
protocol = "imap";
} else {
throw new IOException("Unsupported protocol: "+url.substring(0, url.indexOf("://")));
}
try {
URL newurl = new URL(url);
String path = newurl.getPath();
String query = newurl.getQuery();
authority = newurl.getAuthority();
host = newurl.getHost();
port = newurl.getPort();
username = newurl.getUserInfo();
password = "provide your password here";
foldername = path.substring(path.indexOf(">/")+2, path.lastIndexOf(">"));
msgid = Long.parseLong(path.substring(path.lastIndexOf(">")+1, path.length()));
filename = query.substring(query.indexOf("=")+1, query.length());
} catch (MalformedURLException ex) {
throw ex;
}
} else {
throw new IOException("The given URL is empty or invalid.");
}
}
public File fetchMessage() throws IOException, FileNotFoundException, MessagingException {
Store store = null;
Folder folder = null;
File filepath = new File("/destination/directory");
try {
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", protocol);
Session session = Session.getDefaultInstance(props, null);
// session.setDebug(true);
store = session.getStore(protocol);
store.connect(host, port, username, password);
folder = store.getFolder(foldername);
folder.open(Folder.READ_ONLY);
UIDFolder ufolder = (UIDFolder)folder;
message = ufolder.getMessageByUID(msgid);
if(message!=null) {
File file = null;
if(filename.equals("null")) {
file = new File(filepath.getAbsolutePath()+File.separator+Long.toString(System.nanoTime())+".eml");
} else {
file = new File(filepath.getAbsolutePath()+File.separator+filename);
}
message.writeTo(new FileOutputStream(file));
return file;
} else {
throw new MessagingException("The requested e-mail could not be found on the mail server.");
}
} catch(Exception ex) {
throw ex;
} finally {
if(folder!=null) {
folder.close(true);
}
if(store!=null) {
store.close();
}
}
}
}

How can I access my gmail emails from a Java application?

I want to fetch the emails of my gmail account from Java code. How can I go about doing this?
Here is the Refresh Working Code, that Displays the Email msgs in the console in a proper format along with the Attachments also being Downloaded....
import com.sun.mail.pop3.POP3Folder;
import com.sun.mail.pop3.POP3SSLStore;
import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.MimeBodyPart;
public class MailfetchingPop3
{
private Session session;
private POP3SSLStore store;
private String username;
private String password;
private POP3Folder folder;
public static String numberOfFiles = null;
public static int toCheck = 0;
public static Writer output = null;
URLName url;
public static String receiving_attachments="C:\\download";
public MailfetchingPop3()
{
session = null;
store = null;
}
public void setUserPass(String username, String password)
{
this.username = username;
this.password = password;
}
public void connect()
throws Exception
{
String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
Properties pop3Props = new Properties();
pop3Props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
pop3Props.setProperty("mail.pop3.socketFactory.fallback", "false");
pop3Props.setProperty("mail.pop3.port", "995");
pop3Props.setProperty("mail.pop3.socketFactory.port", "995");
url = new URLName("pop3", "pop.gmail.com", 995, "", username, password);
session = Session.getInstance(pop3Props, null);
store = new POP3SSLStore(session, url);
store.connect();
}
public void openFolder(String folderName)
throws Exception
{
folder = (POP3Folder)store.getFolder(folderName);
System.out.println((new StringBuilder("For test----")).append
(folder.getParent().getFullName()).toString());
if(folder == null)
throw new Exception("Invalid folder");
try
{
folder.open(2);
System.out.println((new StringBuilder("Folder name----")).append
(folder.getFullName()).toString());
}
catch(Exception ex)
{
System.out.println((new StringBuilder("Folder Opening Exception..")).append(ex).toString());
}
}
public void closeFolder()
throws Exception
{
folder.close(false);
}
public int getMessageCount()
throws Exception
{
return folder.getMessageCount();
}
public int getNewMessageCount()
throws Exception
{
return folder.getNewMessageCount();
}
public void disconnect()
throws Exception
{
store.close();
}
public void printAllMessages()
throws Exception
{
Message msgs[] = folder.getMessages();
FetchProfile fp = new FetchProfile();
folder.fetch(msgs, fp);
for(int i = 0; i < msgs.length; i++){
Message message = msgs[i];
dumpEnvelope(msgs[i]);
System.out.println("==============================");
System.out.println("Email #" + (i + 1));
System.out.println("Subject: " + message.getSubject());
System.out.println("From: " + message.getFrom()[0]);
System.out.println("Text: " + message.getContent().toString());
}
}
public static int saveFile(File saveFile, Part part) throws Exception {
BufferedOutputStream bos = new BufferedOutputStream( new
FileOutputStream(saveFile) );
byte[] buff = new byte[2048];
InputStream is = part.getInputStream();
int ret = 0, count = 0;
while( (ret = is.read(buff)) > 0 ){
bos.write(buff, 0, ret);
count += ret;
}
bos.close();
is.close();
return count;
}
private static void dumpEnvelope(Message m) throws Exception
{
String body="";
String path="";
int size=0;
Object content = m.getContent();
if(content instanceof String){
body = (String)content;
}
else 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();
//System.out.println("test disposition---->>"+disposition);
if (disposition == null) {
// Check if plain
MimeBodyPart mbp = (MimeBodyPart)part;
if (mbp.isMimeType("text/plain")) {
body += mbp.getContent().toString();
}
else if (mbp.isMimeType("TEXT/HTML")) {
body += mbp.getContent().toString();
}
else {
//unknown
}
} else if ((disposition != null) &&
(disposition.equals(Part.ATTACHMENT) || disposition.equals
(Part.INLINE) || disposition.equals("ATTACHMENT") || disposition.equals
("INLINE")) )
{
// Check if plain
MimeBodyPart mbp = (MimeBodyPart)part;
if (mbp.isMimeType("text/plain")) {
body += (String)mbp.getContent();
}
else if (mbp.isMimeType("TEXT/HTML")) {
body += mbp.getContent().toString();
}
else {
File savedir = new File(receiving_attachments);
savedir.mkdirs();
File savefile = new File(savedir+"\\"+part.getFileName());
path = savefile.getAbsolutePath();
size = saveFile( savefile, part);
}
}
}
}
}
public static void main(String args[])
{
try
{
MailfetchingPop3 gmail = new MailfetchingPop3();
gmail.setUserPass("your-gmail-username", "your-gmail-password");
gmail.connect();
gmail.openFolder("INBOX");
gmail.printAllMessages();
}
catch(Exception e)
{
e.printStackTrace();
System.exit(-1);
}
}
}
Another option: if you don't mind it being a Gmail-specific solution, note that Gmail also provides an RSS feed to your mailbox, which you can then access with normal XML processing APIs.
Gmail uses IMAP, which Javamail can use. Try to use that in an implementation, and if you get stuck, post some more specific questions here.
Here is the code which fetch mail along with it's attachments (if any) from a gmail account using POST OFFICE PROTOCOL (pop3) .
import com.sun.mail.pop3.POP3Folder;
import com.sun.mail.pop3.POP3SSLStore;
import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.MimeBodyPart;
public class MailfetchingPop3
{
private Session session;
private POP3SSLStore store;
private String username;
private String password;
private POP3Folder folder;
public static String numberOfFiles = null;
public static int toCheck = 0;
public static Writer output = null;
URLName url;
public static String receiving_attachments="C:\\download";
public MailfetchingPop3()
{
session = null;
store = null;
}
public void setUserPass(String username, String password)
{
this.username = username;
this.password = password;
}
public void connect()
throws Exception
{
String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
Properties pop3Props = new Properties();
pop3Props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
pop3Props.setProperty("mail.pop3.socketFactory.fallback", "false");
pop3Props.setProperty("mail.pop3.port", "995");
pop3Props.setProperty("mail.pop3.socketFactory.port", "995");
url = new URLName("pop3", "pop.gmail.com", 995, "", username, password);
session = Session.getInstance(pop3Props, null);
store = new POP3SSLStore(session, url);
store.connect();
}
public void openFolder(String folderName)
throws Exception
{
folder = (POP3Folder)store.getFolder(folderName);
System.out.println((new StringBuilder("For test----")).append(folder.getParent().getFullName()).toString());
if(folder == null)
throw new Exception("Invalid folder");
try
{
folder.open(2);
System.out.println((new StringBuilder("Folder name----")).append(folder.getFullName()).toString());
}
catch(Exception ex)
{
System.out.println((new StringBuilder("Folder Opening Exception..")).append(ex).toString());
}
}
public void closeFolder()
throws Exception
{
folder.close(false);
}
public int getMessageCount()
throws Exception
{
return folder.getMessageCount();
}
public int getNewMessageCount()
throws Exception
{
return folder.getNewMessageCount();
}
public void disconnect()
throws Exception
{
store.close();
}
public void printAllMessages()
throws Exception
{
Message msgs[] = folder.getMessages();
FetchProfile fp = new FetchProfile();
folder.fetch(msgs, fp);
for(int i = 0; i < msgs.length; i++)
dumpEnvelope(msgs[i]);
}
public static int saveFile(File saveFile, Part part) throws Exception {
BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(saveFile) );
byte[] buff = new byte[2048];
InputStream is = part.getInputStream();
int ret = 0, count = 0;
while( (ret = is.read(buff)) > 0 ){
bos.write(buff, 0, ret);
count += ret;
}
bos.close();
is.close();
return count;
}
private static void dumpEnvelope(Message m) throws Exception
{
String body="";
String path="";
int size=0;
Object content = m.getContent();
if(content instanceof String){
body = (String)content;
}
else 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();
//System.out.println("test disposition---->>"+disposition);
if (disposition == null) {
// Check if plain
MimeBodyPart mbp = (MimeBodyPart)part;
if (mbp.isMimeType("text/plain")) {
body += mbp.getContent().toString();
}
else if (mbp.isMimeType("TEXT/HTML")) {
body += mbp.getContent().toString();
}
else {
//unknown
}
} else if ((disposition != null) &&
(disposition.equals(Part.ATTACHMENT) || disposition.equals(Part.INLINE) || disposition.equals("ATTACHMENT") || disposition.equals("INLINE")) )
{
// Check if plain
MimeBodyPart mbp = (MimeBodyPart)part;
if (mbp.isMimeType("text/plain")) {
body += (String)mbp.getContent();
}
else if (mbp.isMimeType("TEXT/HTML")) {
body += mbp.getContent().toString();
}
else {
File savedir = new File(receiving_attachments);
savedir.mkdirs();
File savefile = new File(savedir+"\\"+part.getFileName());
path = savefile.getAbsolutePath();
size = saveFile( savefile, part);
}
}
}
}
}
public static void main(String args[])
{
try
{
MailfetchingPop3 gmail = new MailfetchingPop3();
gmail.setUserPass("your_gmail_Id", "your_gmail_mail_id_password");
gmail.connect();
gmail.openFolder("INBOX");
gmail.printAllMessages();
}
catch(Exception e)
{
e.printStackTrace();
System.exit(-1);
}
}
}
To run this java class you need to download javamail.jar and activation.jar

Categories