Friday, September 27, 2019

Java Swing application to upload files to HTTP server with progress bar

जावा स्विंग एप्लिकेशन को प्रगति बार के साथ HTTP सर्वर पर फाइलें अपलोड करने के लिए

In this tutorial, you will learn how to develop a Java Swing application that allows users uploading a file from his computer to a HTTP server. The application would look like this:
Swing File Upload application
The following diagram explains workflow of the application:
swing file upload application workflow
As we can see, the client is a Swing application that initiates an HTTP POST request to the server. The request must be multipart in order to carry the file to be uploaded. The server side can be implemented in any language as long as it supports parsing HTTP’s multipart request.
For this tutorial, we only discuss how to implement the client side. For the server side, please consult the following tutorials:
The following class diagram gives an idea of how the application would be designed:
swing file upload app class diagram
There are three main classes:
    • MultipartUploadUtility: implements the functionality to upload a file to a server through HTTP’s multipart request. The implementation is based on the tutorial Upload files by sending multipart request programmatically, and is modified to suite requirement of this application: showing progress of the upload.
    • UploadTask: this class extends the javax.swing.SwingWorker class to perform the upload in a background thread so the GUI does not freeze when the progress bar is being updated by the Swing’s event dispatching thread (EDT).
    • SwingFileUploadHTTP: this is the main application which is a JFrame and displays the GUI. It implements the java.beans.PropertyChangeListener interface to be notified about the progress of upload which is sent by the UploadTask class. This class also utilizes the JFilePicker class to show a file chooser component. The JFilePicker in turn, uses the FileTypeFilter class. Refer to the article File picker component in Swing to see how these components are implemented.
Now let’s take closer look at how the main classes are implemented.

1. Code of the MultipartUploadUtility class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package net.codejava.swing.upload;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
 
/**
 * This utility class provides an abstraction layer for sending multipart HTTP
 * POST requests to a web server.
 *
 * @author www.codejava.net
 *
 */
public class MultipartUploadUtility {
    private final String boundary;
    private static final String LINE_FEED = "\r\n";
    private HttpURLConnection httpConn;
    private OutputStream outputStream;
    private PrintWriter writer;
 
    /**
     * This constructor initializes a new HTTP POST request with content type is
     * set to multipart/form-data.
     *
     * @param requestURL
     * @param charset
     * @throws IOException
     */
    public MultipartUploadUtility(String requestURL, String charset)
            throws IOException {
 
        // creates a unique boundary based on time stamp
        boundary = "===" + System.currentTimeMillis() + "===";
 
        URL url = new URL(requestURL);
        httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setDoOutput(true); // indicates POST method
        httpConn.setDoInput(true);
        httpConn.setRequestProperty("Content-Type",
                "multipart/form-data; boundary=" + boundary);
        outputStream = httpConn.getOutputStream();
        writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
                true);
    }
 
    /**
     * Add a upload file section to the request
     *
     * @param fieldName
     *            name attribute in <input type="file" name="..." />
     * @param uploadFile
     *            a File to be uploaded
     * @throws IOException
     */
    public void addFilePart(String fieldName, File uploadFile)
            throws IOException {
        String fileName = uploadFile.getName();
        writer.append("--" + boundary).append(LINE_FEED);
        writer.append(
                "Content-Disposition: form-data; name=\"" + fieldName
                        "\"; filename=\"" + fileName + "\"")
                .append(LINE_FEED);
        writer.append(
                "Content-Type: "
                        + URLConnection.guessContentTypeFromName(fileName))
                .append(LINE_FEED);
        writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
        writer.append(LINE_FEED);
        writer.flush();
    }
 
    /**
     * Write an array of bytes to the request's output stream.
     */
    public void writeFileBytes(byte[] bytes, int offset, int length)
            throws IOException {
        outputStream.write(bytes, offset, length);
    }
 
    /**
     * Complete the request and receives response from the server.
     *
     * @throws IOException
     *             if any network error occurred or the server returns
     *             non-HTTP_OK status code.
     */
    public void finish() throws IOException {
        outputStream.flush();
        writer.append(LINE_FEED);
        writer.flush();
 
        writer.append(LINE_FEED).flush();
        writer.append("--" + boundary + "--").append(LINE_FEED);
        writer.close();
 
        // check server's status code first
        int status = httpConn.getResponseCode();
        if (status == HttpURLConnection.HTTP_OK) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    httpConn.getInputStream()));
            while (reader.readLine() != null) {
                // do nothing, but necessary to consume response from the server
            }
            reader.close();
            httpConn.disconnect();
        else {
            throw new IOException("Server returned non-OK status: " + status);
        }
    }
}

No comments:

Post a Comment

How to DROP SEQUENCE in Oracle?

  Oracle  DROP SEQUENCE   overview The  DROP SEQUENCE  the statement allows you to remove a sequence from the database. Here is the basic sy...