codice:
/**
         * Closes the stream.  

         * 

         * NOTE: This method MUST be called to finalize the
         * multipart stream.
         *
         * @throws  java.io.IOException  on input/output errors
         */
        public void close() throws java.io.IOException {
                // write final boundary
                out.writeBytes(PREFIX);
                out.writeBytes(boundary);
                out.writeBytes(PREFIX);
                out.writeBytes(NEWLINE);
                out.flush();
                out.close();
        }

        /**
         * Gets the multipart boundary string being used by this stream.
         *
         * @return  the boundary
         */
        public String getBoundary() {
                return this.boundary;
        }

        /**
         * Creates a new <code>java.net.URLConnection</code> object from the
         * specified <code>java.net.URL</code>.  This is a convenience method
         * which will set the <code>doInput</code>, <code>doOutput</code>,
         * <code>useCaches</code> and <code>defaultUseCaches</code> fields to
         * the appropriate settings in the correct order.
         *
         * @return  a <code>java.net.URLConnection</code> object for the URL
         * @throws  java.io.IOException  on input/output errors
         */
        public static URLConnection createConnection(URL url)
                        throws java.io.IOException {
                URLConnection urlConn = url.openConnection();
                if(urlConn instanceof HttpURLConnection) {
                        HttpURLConnection httpConn = (HttpURLConnection)urlConn;
                        httpConn.setRequestMethod("POST");
                }
                urlConn.setDoInput(true);
                urlConn.setDoOutput(true);
                urlConn.setUseCaches(false);
                urlConn.setDefaultUseCaches(false);
                return urlConn;
        }

        /**
         * Creates a multipart boundary string by concatenating 20 hyphens (-)
         * and the hexadecimal (base-16) representation of the current time in
         * milliseconds.
         *
         * @return  a multipart boundary string
         * @see  #getContentType(String)
         */
        public static String createBoundary() {
                return "--------------------" +
                        Long.toString(System.currentTimeMillis(), 16);
        }

        /**
         * Gets the content type string suitable for the
         * <code>java.net.URLConnection</code> which includes the multipart
         * boundary string.  

         * 

         * This method is static because, due to the nature of the
         * <code>java.net.URLConnection</code> class, once the output stream
         * for the connection is acquired, it's too late to set the content
         * type (or any other request parameter).  So one has to create a
         * multipart boundary string first before using this class, such as
         * with the <code>createBoundary()</code> method.
         *
         * @param  boundary  the boundary string
         * @return  the content type string
         * @see  #createBoundary()
         */
        public static String getContentType(String boundary) {
                return "multipart/form-data; boundary=" + boundary;
        }
public static void main (String[] args) {
          try {
            URL url = new URL("http://miosito.com/doupload.php");
            // create a boundary string
            String boundary = MultiPartFormOutputStream.createBoundary();
            URLConnection urlConn = MultiPartFormOutputStream.createConnection(url);
            urlConn.setRequestProperty("Accept", "*/*");
            urlConn.setRequestProperty("Content-Type",
                                       MultiPartFormOutputStream.getContentType(boundary));
            // set some other request headers...
            urlConn.setRequestProperty("Connection", "Keep-Alive");
            urlConn.setRequestProperty("Cache-Control", "no-cache");
            // no need to connect cuz getOutputStream() does it
            MultiPartFormOutputStream out =  new MultiPartFormOutputStream(urlConn.getOutputStream(), boundary);
            // write a text field element
            //out.writeField("myText", "text field text");
            // upload a file
            out.writeFile("file", "text/plain", new File("C:\\Documents and Settings\\Andrea\\Desktop\\codicefiscale.html"));
            // can also write bytes directly
            //out.writeFile("myFile", "text/plain", "C:\\test.txt",
            //	"This is some file text.".getBytes("ASCII"));
            //out.flush();
            out.close();
            // read response from server
            BufferedReader in = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
            String line = "";
            while((line = in.readLine()) != null) {
              System.out.println(line);
            }
            in.close();
          }
          catch (Exception e) {
            e.printStackTrace();
          }
        }
}
Il main l'ho aggiunto io per fare un po' di test, così come suggerito nel post originale stesso.

La pagina doupload.php è una banalissima cosa del genere:
codice:
<?php
  if(isset($_FILES)) {
    $public_folder = "/web/htdocs/www.miosito.com/home/javaupload";
    $docs = $_FILES['file']['name'];
    $tempname = $_FILES['file']['tmp_name'];
    $log ="";    
    $ext = strrchr($docs, ".");
    $newnamedocs = preg_replace("/(\W)+/","_",substr($docs,0,strrpos($docs,"."))).$ext;
    @move_uploaded_file($tempname, $public_folder."/".$newnamedocs);
  }
?>
<html>
<body>
<form enctype="multipart/form-data" action="upload.php" method="POST">
    <input name="file" type="file" />
    <input type="submit" value="Send File" />
</form>
</body>
</html>
In cui faccio un po' di pulizia di caratteri potenzialmente nocivi dal nome del file di destinazione. Funziona... ma ripeto, adesso devi infilarlo dentro un applet firmata e l'applet dovrai andarla a mettere nel tuo sito.