This week's book giveaway is in the OCMJEA forum.
We're giving away four copies of OCM Java EE 6 Enterprise Architect Exam Guide and have Paul Allen & Joseph Bambara on-line!
See this thread for details.
The moose likes JSP and the fly likes Using FTP in jsp Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Java » JSP
Bookmark "Using FTP in jsp" Watch "Using FTP in jsp" New topic
Author

Using FTP in jsp

Prabhu Chandrasekaran
Ranch Hand

Joined: Oct 14, 2000
Posts: 36
Hi friends,
The following is a generic java file used for FTP uploads
--------------------------------------------------
/**
* File: FTPConnection.java
* Author: Bret Taylor <btaylor@cs.stanford.edu>
* ---------------------------------------------
* $Id$
* ---------------------------------------------
* Parts of this code were adopted from a variety of other FTP classes the
* author has encountered that he was not completely satisfied with. If you
* think more thanks are due to any particular author than is given, please
* let him know. With that caveat, this class can be freely distributed and
* modified as long as Bret Taylor is given credit in the source code comments.
*/
import java.io.*;
import java.net.*;
import java.util.*;
/**
* <p>A wrapper for the network and command protocols needed for the most common
* FTP commands. Standard usage looks something like this:</p>
* <pre> FTPConnection connection = new FTPConnection();
* try {
* if (connection.connect(host)) {
* if (connection.login(username, password)) {
* connection.downloadFile(serverFileName);
* connection.uploadFile(localFileName);
* }
* connection.disconnect();
* }
* } catch (UnknownHostException e) {
* // handle unknown host
* } catch (IOException e) {
* // handle I/O exception
* }</pre>
* <p>Most FTP commands are wrapped by easy-to-use methods, but in case clients
* need more flexibility, you can execute commands directly using the methods
* <a href="#executeCommand(java.lang.String)">executeCommand</a> and
* <a href="#executeDataCommand(java.lang.String, java.io.OutputStream)">executeDataCommand</a>,
* the latter of which is used for commands that require an open data port.</p>
*
* @author Bret Taylor
* @version 1.0
*/
public class FTPConnection extends Object {
/**
* If this flag is on, we print out debugging information to stdout during
* execution. Useful for debugging the FTP class and seeing the server's
* responses directly.
*/
private static boolean PRINT_DEBUG_INFO = false;
/**
* Connects to the given FTP host on port 21, the default FTP port.
*/
public boolean connect(String host)
throws UnknownHostException, IOException
{
return connect(host, 21);
}
/**
* Connects to the given FTP host on the given port.
*/
public boolean connect(String host, int port)
throws UnknownHostException, IOException
{
connectionSocket = new Socket(host, port);
outputStream = new PrintStream(connectionSocket.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
if (!isPositiveCompleteResponse(getServerReply())){
disconnect();
return false;
}
return true;
}
/**
* Disconnects from the host to which we are currently connected.
*/
public void disconnect()
{
if (outputStream != null) {
try {
outputStream.close();
inputStream.close();
connectionSocket.close();
} catch (IOException e) {}
outputStream = null;
inputStream = null;
connectionSocket = null;
}
}
/**
* Wrapper for the commands <code>user [username]</code> and <code>pass
* [password]</code>.
*/
public boolean login(String username, String password)
throws IOException
{
int response = executeCommand("user " + username);
if (!isPositiveIntermediateResponse(response)) return false;
response = executeCommand("pass " + password);
return isPositiveCompleteResponse(response);
}
/**
* Wrapper for the command <code>cwd [directory]</code>.
*/
public boolean changeDirectory(String directory)
throws IOException
{
int response = executeCommand("cwd " + directory);
return isPositiveCompleteResponse(response);
}
/**
* Wrapper for the commands <code>rnfr [oldName]</code> and <code>rnto
* [newName]</code>.
*/
public boolean renameFile(String oldName, String newName)
throws IOException
{
int response = executeCommand("rnfr " + oldName);
if (!isPositiveIntermediateResponse(response)) return false;
response = executeCommand("rnto " + newName);
return isPositiveCompleteResponse(response);
}

/**
* Wrapper for the command <code>mkd [directory]</code>.
*/
public boolean makeDirectory(String directory)
throws IOException
{
int response = executeCommand("mkd " + directory);
return isPositiveCompleteResponse(response);
}

/**
* Wrapper for the command <code>rmd [directory]</code>.
*/
public boolean removeDirectory(String directory)
throws IOException
{
int response = executeCommand("rmd " + directory);
return isPositiveCompleteResponse(response);
}

/**
* Wrapper for the command <code>cdup</code>.
*/
public boolean parentDirectory()
throws IOException
{
int response = executeCommand("cdup");
return isPositiveCompleteResponse(response);
}

/**
* Wrapper for the command <code>dele [fileName]</code>.
*/
public boolean deleteFile(String fileName)
throws IOException
{
int response = executeCommand("dele " + fileName);
return isPositiveCompleteResponse(response);
}

/**
* Wrapper for the command <code>pwd</code>.
*/
public String getCurrentDirectory()
throws IOException
{
String response = getExecutionResponse("pwd");
StringTokenizer strtok = new StringTokenizer(response);
// Get rid of the first token, which is the return code
if (strtok.countTokens() < 2) return null;
strtok.nextToken();
String directoryName = strtok.nextToken();
// Most servers surround the directory name with quotation marks
int strlen = directoryName.length();
if (strlen == 0) return null;
if (directoryName.charAt(0) == '\"') {
directoryName = directoryName.substring(1);
strlen--;
}
if (directoryName.charAt(strlen - 1) == '\"')
return directoryName.substring(0, strlen - 1);
return directoryName;
}

/**
* Wrapper for the command <code>syst</code>.
*/
public String getSystemType()
throws IOException
{
return excludeCode(getExecutionResponse("syst"));
}

/**
* Wrapper for the command <code>mdtm [fileName]</code>. If the file does
* not exist, we return -1;
*/
public long getModificationTime(String fileName)
throws IOException
{
String response = excludeCode(getExecutionResponse("mdtm " + fileName));
try {
return Long.parseLong(response);
} catch (Exception e) {
return -1L;
}
}

/**
* Wrapper for the command <code>size [fileName]</code>. If the file does
* not exist, we return -1;
*/
public long getFileSize(String fileName)
throws IOException
{
String response = excludeCode(getExecutionResponse("size " + fileName));
try {
return Long.parseLong(response);
} catch (Exception e) {
return -1L;
}
}
/**
* Wrapper for the command <code>retr [fileName]</code>.
*/
public boolean downloadFile(String fileName)
throws IOException
{
return readDataToFile("retr " + fileName, fileName);
}
/**
* Wrapper for the command <code>retr [serverPath]</code>. The local file
* path to which we will write is given by <code>localPath</code>.
*/
public boolean downloadFile(String serverPath, String localPath)
throws IOException
{
return readDataToFile("retr " + serverPath, localPath);
}
/**
* Wrapper for the command <code>stor [fileName]</code>.
*/
public boolean uploadFile(String fileName)
throws IOException
{
return writeDataFromFile("stor " + fileName, fileName);
}
/**
* Wrapper for the command <code>stor [localPath]</code>. The server file
* path to which we will write is given by <code>serverPath</code>.
*/
public boolean uploadFile(String serverPath, String localPath)
throws IOException
{
return writeDataFromFile("stor " + serverPath, localPath);
}
/**
* Set the restart point for the next download or upload operation. This
* lets clients resume interrupted uploads or downloads.
*/
public void setRestartPoint(int point)
{
restartPoint = point;
debugPrint("Restart noted");
}
/**
* Gets server reply code from the control port after an ftp command has
* been executed. It knows the last line of the response because it begins
* with a 3 digit number and a space, (a dash instead of a space would be a
* continuation).
*/
private int getServerReply()
throws IOException
{
return Integer.parseInt(getFullServerReply().substring(0, 3));
}
/**
* Gets server reply string from the control port after an ftp command has
* been executed. This consists only of the last line of the response,
* and only the part after the response code.
*/
private String getFullServerReply()
throws IOException
{
String reply;
do {
reply = inputStream.readLine();
debugPrint(reply);
} while(!(Character.isDigit(reply.charAt(0)) &&
Character.isDigit(reply.charAt(1)) &&
Character.isDigit(reply.charAt(2)) &&
reply.charAt(3) == ' '));
return reply;
}
/**
* Executes the given FTP command on our current connection, returning the
* three digit response code from the server. This method only works for
* commands that do not require an additional data port.
*/
public int executeCommand(String command)
throws IOException
{
outputStream.println(command);
return getServerReply();
}
/**
* Executes the given FTP command on our current connection, returning the
* last line of the server's response. Useful for commands that return
* one line of information.
*/
public String getExecutionResponse(String command)
throws IOException
{
outputStream.println(command);
return getFullServerReply();
}
/**
* Executes the given ftpd command on the server and writes the results
* returned on the data port to the file with the given name, returning true
* if the server indicates that the operation was successful.
*/
public boolean readDataToFile(String command, String fileName)
throws IOException
{
// Open the local file
RandomAccessFile outfile = new RandomAccessFile(fileName, "rw");
// Do restart if desired
if (restartPoint != 0) {
debugPrint("Seeking to " + restartPoint);
outfile.seek(restartPoint);
}
// Convert the RandomAccessFile to an OutputStream
FileOutputStream fileStream = new FileOutputStream(outfile.getFD());
boolean success = executeDataCommand(command, fileStream);
outfile.close();
return success;
}
/**
* Executes the given ftpd command on the server and writes the contents
* of the given file to the server on an opened data port, returning true
* if the server indicates that the operation was successful.
*/
public boolean writeDataFromFile(String command, String fileName)
throws IOException
{
// Open the local file
RandomAccessFile infile = new RandomAccessFile(fileName, "r");
// Do restart if desired
if (restartPoint != 0) {
debugPrint("Seeking to " + restartPoint);
infile.seek(restartPoint);
}
// Convert the RandomAccessFile to an InputStream
FileInputStream fileStream = new FileInputStream(infile.getFD());
boolean success = executeDataCommand(command, fileStream);
infile.close();
return success;
}
/**
* Executes the given ftpd command on the server and writes the results
* returned on the data port to the given OutputStream, returning true
* if the server indicates that the operation was successful.
*/
public boolean executeDataCommand(String command, OutputStream out)
throws IOException
{
// Open a data socket on this computer
ServerSocket serverSocket = new ServerSocket(0);
if (!setupDataPort(command, serverSocket)) return false;
Socket clientSocket = serverSocket.accept();
// Transfer the data
InputStream in = clientSocket.getInputStream();
transferData(in, out);
// Clean up the data structures
in.close();
clientSocket.close();
serverSocket.close();
return isPositiveCompleteResponse(getServerReply());
}
/**
* Executes the given ftpd command on the server and writes the contents
* of the given InputStream to the server on an opened data port, returning
* true if the server indicates that the operation was successful.
*/
public boolean executeDataCommand(String command, InputStream in)
throws IOException
{
// Open a data socket on this computer
ServerSocket serverSocket = new ServerSocket(0);
if (!setupDataPort(command, serverSocket)) return false;
Socket clientSocket = serverSocket.accept();
// Transfer the data
OutputStream out = clientSocket.getOutputStream();
transferData(in, out);
// Clean up the data structures
out.close();
clientSocket.close();
serverSocket.close();
return isPositiveCompleteResponse(getServerReply());
}
/**
* Transfers the data from the given input stream to the given output
* stream until we reach the end of the stream.
*/
private void transferData(InputStream in, OutputStream out)
throws IOException
{
byte b[] = new byte[1024]; // 1K blocks I guess
int amount;
// Read the data into the file
while ((amount = in.read(b)) > 0) {
out.write(b, 0, amount);
}
}
/**
* Executes the given ftpd command on the server and writes the results
* returned on the data port to the given FilterOutputStream, returning true
* if the server indicates that the operation was successful.
*/
private boolean setupDataPort(String command, ServerSocket serverSocket)
throws IOException
{
// Send our local data port to the server
if (!openPort(serverSocket)) return false;
// Set binary type transfer
outputStream.println("type i");
if (!isPositiveCompleteResponse(getServerReply())) {
debugPrint("Could not set transfer type");
return false;
}
// If we have a restart point, send that information
if (restartPoint != 0) {
outputStream.println("rest " + restartPoint);
restartPoint = 0;
// TODO: Interpret server response here
getServerReply();
}
// Send the command
outputStream.println(command);
return isPositivePreliminaryResponse(getServerReply());
}
/**
* Get IP address and port number from serverSocket and send them via the
* <code>port</code> command to the ftp server, returning true if we get a
* valid response from the server, returning true if the server indicates
* that the operation was successful.
*/
private boolean openPort(ServerSocket serverSocket)
throws IOException
{
int localport = serverSocket.getLocalPort();
// get local ip address
InetAddress inetaddress = serverSocket.getInetAddress();
InetAddress localip;
try {
localip = inetaddress.getLocalHost();
} catch(UnknownHostException e) {
debugPrint("Can't get local host");
return false;
}
// get ip address in high byte order
byte[] addrbytes = localip.getAddress();
// tell server what port we are listening on
short addrshorts[] = new short[4];
// problem: bytes greater than 127 are printed as negative numbers
for(int i = 0; i <= 3; i++) {
addrshorts[i] = addrbytes[i];
if (addrshorts[i] < 0)
addrshorts[i] += 256;
}
outputStream.println("port " + addrshorts[0] + "," + addrshorts[1] +
"," + addrshorts[2] + "," + addrshorts[3] + "," +
((localport & 0xff00) >> 8) + "," +
(localport & 0x00ff));
return isPositiveCompleteResponse(getServerReply());
}
/**
* True if the given response code is in the 100-199 range.
*/
private boolean isPositivePreliminaryResponse(int response)
{
return (response >= 100 && response < 200);
}
/**
* True if the given response code is in the 300-399 range.
*/
private boolean isPositiveIntermediateResponse(int response)
{
return (response >= 300 && response < 400);
}
/**
* True if the given response code is in the 200-299 range.
*/
private boolean isPositiveCompleteResponse(int response)
{
return (response >= 200 && response < 300);
}
/**
* True if the given response code is in the 400-499 range.
*/
private boolean isTransientNegativeResponse(int response)
{
return (response >= 400 && response < 500);
}
/**
* True if the given response code is in the 500-599 range.
*/
private boolean isPermanentNegativeResponse(int response)
{
return (response >= 500 && response < 600);
}
/**
* Eliminates the response code at the beginning of the response string.
*/
private String excludeCode(String response)
{
if (response.length() < 5) return response;
return response.substring(4);
}
/**
* Prints debugging information to stdout if the private flag
* <code>PRINT_DEBUG_INFO</code> is turned on.
*/
private void debugPrint(String message) {
if (PRINT_DEBUG_INFO) System.err.println(message);
}
/**
* The socket through which we are connected to the FTP server.
*/
private Socket connectionSocket = null;
/**
* The socket output stream.
*/
private PrintStream outputStream = null;
/**
* The socket input stream.
*/
private BufferedReader inputStream = null;
/**
* The offset at which we resume a file transfer.
*/
private long restartPoint = 0L;
}
--------------------------------------------------
The following is the jsp file that uses the FTPConnection java file
--------------------------------------------------
<%@page import="java.io.*,FTPConnection"%>
<html>
<title> FTP Try Jsp </title>
<%
String mfilename=request.getParameter("mfilename");
try
{
FTPConnection fconnect = new FTPConnection();
fconnect.connect("193.1.1.6");
// login //
fconnect.login("userpos","userpos");
fconnect.changeDirectory("../kws/library");
out.println("<B>"+fconnect.getCurrentDirectory()+"</b><BR>");
fconnect.uploadFile(mfilename);
fconnect.disconnect();
}
catch(Exception ex)
{
out.println("EXception caused :: "+ex+"<BR>");
}
%>
--------------------------------------------------
The file to be ported is got from the user via a <input type=file> tag and onSubmit the above jsp file is called. This throws an FileNotFoundException as it is unable to recognise that the file selected is from the local hard disk.
Can anyone help me out ??
It is Urgent.
Advance Thanks,
Prabhu.V.C
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16022
    
  20

It's all very nice, but on a JSP, you wouldn't be using an FTP upload, you'd be using an HTTP upload. All that code is redundant, because the browser does the transferring.
If you actually wanted to trigger an upload to an FTP server, that gets a little more complex, because the FTP server is potentially not the same machine as the HTTP server, which can get you involved in "sandbox" considerations.
You might want to take a look at the O'Reilly multi-part MIME upload code - I believe there's a copy - and possibly some annotations - here at the JavaRanch.


Customer surveys are for companies who didn't pay proper attention to begin with.
Prabhu Chandrasekaran
Ranch Hand

Joined: Oct 14, 2000
Posts: 36
Hi,
Thanks for the reply. Can u send me the code for Multipart MIME transfer. My mail ID is prabhu_vc@yahoo.com.
Advance Thanks,
Prabhu.V.C
Dave Vick
Ranch Hand

Joined: May 10, 2001
Posts: 3244
Prabhu
Two things:
1. If you are posting code of more than a few lines enclosing it in ubb code tags makes it much more readable.
2. While posting code helps out most of the tiem you should try to post just the relevant sections of code to the problem. there is no need to post all of the code becasue many people might not try to read it because of its size.


Dave
Prabhu Chandrasekaran
Ranch Hand

Joined: Oct 14, 2000
Posts: 36
Hi Dave,
Thanks. Henceforth I will follow your advice.
Regards,
Prabhu.V.C
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Using FTP in jsp