tags:

views:

66

answers:

5

Hi,

I have a java servlet which accepts an image a user uploads to my web app.

I have another server (running php) which will host all the images. How can I get an image from my jsp server to my php server? The flow would be something like:

public class ServletImgUpload extends HttpServlet 
{   
    public void doPost(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException 
    {
        // get image user submitted
        // try sending it to my php server now
        // return success or failure message back to user
    }
}

Thanks

A: 

For the sending part, you could use something like HttpClient. You should use POST requests with multipart "encoding", and add file parts.

Since you have to send it to a PHP server I suggest you simply bypass the servlet and send the file directly to the PHP server instead, or, if not possible, just proxy the request to the PHP server.

Artefacto
A: 

Well, you could setup a simple web service on your PHP server that accepts an image as a post upload.

Once you have that setup, you can send the image via post, using something like HttpClient.

xil3
+2  A: 

A few solutions off the top of my head...

  • Use HTTP POST to send the file. Probably not a good idea if the files are large.
  • Use FTP. This easily gives you authentication, handling of large files, etc. Bonus points for using SFTP.
  • Use a program like rsync [over ssh] to migrate the directory contents from one server to the other. Not a good solution if you have disk space concerns since you'd be storing the same files twice, once per server.

Also, remember to consider how often images are going to be pushed to your servlet. You don't want to try holding 100s of images and their transfers' network sockets in memory - save the images to the disk in this instance.

Sam Bisbee
I just used the Apache Commons Net (http://commons.apache.org/net/) package in my most recent java project, and it's dead-simple to use for FTP. Although not as secure as SFTP (SSH FTP), it supports FTPS (FTP with SSL).
HalfBrian
Rsync is a great solution if you are moving the same directory often. It offers great security (via ssh) and compression. However, for moving single files, FTP might be a better choice here, just because it seems like the file will be moved, and then removed.
Chris Henry
@Chris: Yeah, I assumed that all of the uploaded images would be saved into a common structure. Even if it's a multi-tier directory structure, you can rsync the whole tree over, though that could include other files (ex., the whole web root). One nice thing is that this seamlessly supports file deletion and updates.
Sam Bisbee
A: 

First of all, why don't you just submit the form directly to that PHP script?

<form action="http://example.com/upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit">
</form>

If this is somehow not an option and you really need to submit the form to the servlet, then first create a HTML form like following in the JSP:

<form action="upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit">
</form>

In the servlet which listens on an url-pattern of /upload, you have 2 options to handle the request, depending on what the PHP script takes.

If the PHP script takes the same parameters and can process the uploaded file the same way as the HTML form has instructed the servlet to do (I would still rather just let the form submit directly to the PHP script, but anyway), then you can let the servlet play for a transparent proxy which just transfers the bytes immediately from the HTTP request to the PHP script. The java.net.URLConnection API is useful in this.

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    HttpURLConnection connection = (HttpURLConnection) new URL("http://example.com/upload.php").openConnection();
    connection.setDoOutput(true); // POST.
    connection.setRequestProperty("Content-Type", request.getHeader("Content-Type")); // This one is important! You may want to check other request headers and copy it as well.

    // Set streaming mode, else HttpURLConnection will buffer everything in Java's memory.
    int contentLength = request.getContentLength();
    if (contentLength > -1) {
        connection.setFixedLengthStreamingMode(contentLength);
     } else {
        connection.setChunkedStreamingMode(1024);
    }

    InputStream input = request.getInputStream();
    OutputStream output = connection.getOutputStream();
    byte[] buffer = new byte[1024]; // Uses only 1KB of memory!
    for (int length = 0; (length = input.read(buffer)) > 0;) {
        output.write(buffer, 0, length);
    }
    output.close();

    InputStream phpResponse = connection.getInputStream(); // Calling getInputStream() is important, it's lazily executed!
    // Do your thing with the PHP response.
}

If the PHP script takes different or more parameters (again, I would rather just alter the HTML form accordingly so that it can directly submit to the PHP script), then you can use use Apache Commons FileUpload to extract the uploaded file and Apache HttpComponents Client to submit the uploaded file to the PHP script as if it's submitted from a HTML form.

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    InputStream fileContent = null;
    String fileContentType = null;
    String fileName = null;

    try {
        List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
        for (FileItem item : items) {
            if (!item.isFormField() && item.getFieldName().equals("file")) { // <input type="file" name="file">
                fileContent = item.getInputStream();
                fileContentType = item.getContentType();
                fileName = FilenameUtils.getName(item.getName());
                break; // If there are no other fields?
            }            
        }
    } catch (FileUploadException e) {
        throw new ServletException("Parsing file upload failed.", e);
    }

    if (fileContent != null) {
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost("http://example.com/upload.php");
        MultipartEntity entity = new MultipartEntity();
        entity.addPart("file", new InputStreamBody(fileContent, fileContentType, fileName));
        httpPost.setEntity(entity);
        HttpResponse phpResponse = httpClient.execute(httpPost);
        // Do your thing with the PHP response.
    }
}

See also:

BalusC
A: 

Why upload? Just download the file using php file_get_contents()

On file reception use java to call a url like http://php.example.com/getfile.php?file=file001.jpg

Then in PHP getfile.php:

$file = file_get_contents('http://java.example.com/images/file001.jpg');

Paul