Search code examples
javajavascriptftpapache-commons

Apache Commons FTP Applet upload on html button


Longtime searcher, first time asking a question on stack overflow. I always seem to be able to find my answer by searching, except for this time :)

I'm somewhat of a beginner to programming in Java. Though I think an applet using apache commons ftp is the best solution to achieving an FTP file upload solution in my website.

I've been able to transfer files when I have all my code within my init() method.

Though when I move my code to another method, which I call within javascript, it fails after printing the working directory (PWD).

This code works:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication2;

import java.io.IOException;
import javax.swing.JApplet;
import javax.swing.*;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.io.Util;
import org.apache.commons.net.io.CopyStreamAdapter;
import org.apache.commons.net.io.CopyStreamEvent;
import org.apache.commons.net.io.CopyStreamListener;
/**
 *
 * @author Mike
 */
public class FTPMain extends JApplet {
    int userId;
    private File[] files;
    final JPanel myPanel = new JPanel();
    final JLabel lblStatus = new JLabel();    
    final JProgressBar myProgressBar = new JProgressBar();

    //Called when this applet is loaded into the browser.
    public void init() {

        JButton btnSelectFiles = new JButton("Select Files");
        JButton btnUpload = new JButton("Upload Files");

        myPanel.add(btnSelectFiles);
        myPanel.add(btnUpload);
        myPanel.add(lblStatus);
        myPanel.add(myProgressBar);
        myPanel.setBackground(Color.white);

        btnSelectFiles.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 final JFileChooser fc = new JFileChooser();
                 fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                 fc.setMultiSelectionEnabled(true);
                 int returnVal = fc.showOpenDialog(myPanel);
                 if(returnVal == JFileChooser.APPROVE_OPTION) {
                     files = fc.getSelectedFiles(); 
                     //for(int i = 0; i < files.length; i++) {
                     lblStatus.setText("File count:  " + files.length);
                     //}
                 } else {
                    lblStatus.setText("Open command cancelled by user.");
                 }
             }
        });

        btnUpload.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                lblStatus.setText("Uploading Files...");

                final FTPClient ftpclient = new FTPClient();
                //ftpclient.setControlKeepAliveTimeout(300);
                File myFile;
                try {

                    FTPUtils.ftpConnect(ftpclient, "myhost", "myusername", "mypassword");
                    //ftpclient.enterLocalPassiveMode();
                    ftpclient.setFileType(FTP.BINARY_FILE_TYPE);

                    for(int i = 0; i < files.length; i++) {
                        String to = "/path/to/files/queue";
                        ftpclient.changeWorkingDirectory(to);
                        ftpclient.printWorkingDirectory();
                        myFile = new File(files[i].getAbsolutePath());
                        final String remoteFile = myFile.getName();
                        final InputStream inputStream = new FileInputStream(myFile);
                        final OutputStream outputStream = ftpclient.storeFileStream(remoteFile);

                        //byte[] bytesIn = new byte[4096];
                        //int read = 0;
                        int streamSize = (int)files[i].getTotalSpace();
                        Util.copyStream(inputStream, outputStream, 4096, streamSize, myListener);

                        /*while((read = inputStream.read(bytesIn)) != -1) {
                            outputStream.write(bytesIn, 0, read);
                        }*/

                        inputStream.close();
                        outputStream.close();
                        boolean completed = ftpclient.completePendingCommand();

                        if(completed) {
                            lblStatus.setText((i+1) + " files have been uploaded successfully.");
                        }
                    }
                } catch (IOException ex) {
                    // TODO Auto-generated catch block
                    lblStatus.setText(ex.getMessage());
                    //ex.printStackTrace();
                }
            }
        });

        getContentPane().add(myPanel);
    }

    public CopyStreamListener myListener = new CopyStreamListener(){
        //private long megsTotal = 0;
        public void bytesTransferred(CopyStreamEvent event) {
            bytesTransferred(event.getTotalBytesTransferred(), event.getBytesTransferred(), event.getStreamSize());
        }

        public void bytesTransferred(long totalBytesTransferred,
                int bytesTransferred, long streamSize) {

            final int percent = (bytesTransferred / (int)streamSize) * 100;
            //myProgressBar.setString("Processing " + percent + "%");
            //myProgressBar.setValue(percent);
            lblStatus.setText("Total: "+percent);
            /*long megs = totalBytesTransferred / 1000000;
            for (long l = megsTotal; l < megs; l++) {
                System.err.print("#");
            }
            megsTotal = megs;
            myLabel.setText("Total: " + megsTotal);
            myProgressBar.setValue((int)megsTotal);*/
        }
    };

    //private static CopyStreamListener createListener(){
    //    return 
    //}

    public void startFTPUpload(String strUserInfo) {

        //myLabel.setText("UserId " + userId + " is now set.");
    }
}

Though when I move the file transfering code (within btnUpload Action Listener) to the startFTPUpload method, and run it via javascript, it fails after the PWD line, without an error.

/* javascript code */
$("#btnUpload").click(function() {
    var val = $(this).val();
    var myApp = document.applets["FTPUpload"];
    if(myApp) { 
        //alert("found app");
        myApp.startFTPUpload(val);
    }                     
});
/* ----------------- */

public void startFTPUpload(String strUserInfo) {
        lblStatus.setText("Uploading Files...");

        final FTPClient ftpclient = new FTPClient();
        //ftpclient.setControlKeepAliveTimeout(300);
        File myFile;
        try {

            FTPUtils.ftpConnect(ftpclient, "myhost", "myusername", "mypassword");
            //ftpclient.enterLocalPassiveMode();
            ftpclient.setFileType(FTP.BINARY_FILE_TYPE);

            for(int i = 0; i < files.length; i++) {
                String to = "/path/to/files/queue";
                ftpclient.changeWorkingDirectory(to);
                ftpclient.printWorkingDirectory();
                myFile = new File(files[i].getAbsolutePath());
                final String remoteFile = myFile.getName();
                final InputStream inputStream = new FileInputStream(myFile);
                final OutputStream outputStream = ftpclient.storeFileStream(remoteFile);

                //byte[] bytesIn = new byte[4096];
                //int read = 0;
                int streamSize = (int)files[i].getTotalSpace();
                Util.copyStream(inputStream, outputStream, 4096, streamSize, myListener);

                /*while((read = inputStream.read(bytesIn)) != -1) {
                    outputStream.write(bytesIn, 0, read);
                }*/

                inputStream.close();
                outputStream.close();
                boolean completed = ftpclient.completePendingCommand();

                if(completed) {
                    lblStatus.setText((i+1) + " files have been uploaded successfully.");
                }
            }
        } catch (IOException ex) {
            // TODO Auto-generated catch block
            lblStatus.setText(ex.getMessage());
            //ex.printStackTrace();
        }
        //myLabel.setText("UserId " + userId + " is now set.");
    }

Any help is greatly appreciated, and remember I am a Java beginner. I may not be using the correct methods, open to suggestions.

Thanks! Mike


Solution

  • I figured it out, I needed to wrap the method that was being called by javascript in AccessController.doPrivileged, like below:

    public void startFTPUpload(String strUserInfo) {
        AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
            public Boolean run() {
                try {
                    final FTPClient ftpclient = new FTPClient();
    
                    File myFile;
                    try {
    
                        FTPUtils.ftpConnect(ftpclient, "host", "username", "password");
                        ftpclient.setFileType(FTP.BINARY_FILE_TYPE);
    
                        for(int i = 0; i < files.length; i++) {
                            String to = "/tekmtn.com/sites/testingsite.com/files/queue";
                            ftpclient.changeWorkingDirectory(to);
                            ftpclient.printWorkingDirectory();
                            myFile = new File(files[i].getAbsolutePath());
                            final String remoteFile = myFile.getName();
    
                            FTPUtils.uploadFile(ftpclient, files[i].getAbsolutePath(), remoteFile);
                            boolean completed = ftpclient.completePendingCommand();
                            if(completed) {
                                lblStatus.setText((i+1) + " files have been uploaded successfully.");
                            }
                        }
                    } catch (IOException ex) {
                        // TODO Auto-generated catch block
                        lblStatus.setText(ex.getMessage());
                        //ex.printStackTrace();
                    }
                    //myLabel.setText("UserId " + userId + " is now set.");
                } catch (Exception e) {
                    lblStatus.setText(e.getMessage());
                }
                return Boolean.TRUE;
            }
        });
    }