【问题标题】:Upload and POST file to PHP page with Java使用 Java 将文件上传和 POST 到 PHP 页面
【发布时间】:2010-11-21 19:17:58
【问题描述】:

我需要一种上传文件并将其发布到 php 页面的方法...

我的php页面是:

<?php 
$maxsize = 10485760;
$array_estensioni_ammesse=array('.tmp');
$uploaddir = 'uploads/';
if (is_uploaded_file($_FILES['file']['tmp_name']))
{
    if($_FILES['file']['size'] <= $maxsize)
    {
        $estensione = strtolower(substr($_FILES['file']['name'], strrpos($_FILES['file']['name'], "."), strlen($_FILES['file']['name'])-strrpos($_FILES['file']['name'], ".")));
        if(!in_array($estensione, $array_estensioni_ammesse))
        {
            echo "File is not valid!\n";
        }
        else
        {
            $uploadfile = $uploaddir . basename($_FILES['file']['name']); 
            echo "File ". $_FILES['file']['name'] ." uploaded successfully.\n"; 
            if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile))
            {
                echo "File is valid, and was successfully moved.\n";
            } 
            else 
                print_r($_FILES); 
        }
    }
    else
        echo "File is not valid!\n";
}
else
{ 
    echo "Upload Failed!!!"; 
    print_r($_FILES);
} 
?>

我在我的桌面应用程序中使用这个 java 代码:

HttpURLConnection httpUrlConnection = (HttpURLConnection)new URL("http://www.mypage.org/upload.php").openConnection();
        httpUrlConnection.setDoOutput(true);
        httpUrlConnection.setRequestMethod("POST");
        OutputStream os = httpUrlConnection.getOutputStream();
        Thread.sleep(1000);
        BufferedInputStream fis = new BufferedInputStream(new FileInputStream("tmpfile.tmp"));

        long totalByte = fis.available();
        long byteTrasferred = 0;
        for (int i = 0; i < totalByte; i++) {
            os.write(fis.read());
            byteTrasferred = i + 1;
        }

        os.close();
        BufferedReader in = new BufferedReader(
                new InputStreamReader(
                httpUrlConnection.getInputStream()));

        String s = null;
        while ((s = in.readLine()) != null) {
            System.out.println(s);
        }
        in.close();
        fis.close();

但我总是收到“上传失败!!!”消息。

【问题讨论】:

  • @Albe 找不到变量 totalBytebyteTrasferred 。这些变量的值是多少?

标签: java php post upload


【解决方案1】:

即使线程很老,可能仍然有人在寻找更简单的方法来解决这个问题(比如我:))

经过一番研究,我找到了一种在不更改原始海报 Java 代码的情况下上传文件的方法。 您只需要使用以下 PHP 代码:

<?php
  $filename="abc.xyz";
  $fileData=file_get_contents('php://input');
  $fhandle=fopen($filename, 'wb');
  fwrite($fhandle, $fileData);
  fclose($fhandle);
  echo("Done uploading");
?>

此代码只是获取 java 应用程序发送的原始数据并将其写入文件。 然而,有一个问题:你没有得到原始文件名,所以你必须以其他方式传输它。

我通过使用 GET 参数解决了这个问题,这对 Java 代码进行了一些必要的更改:

HttpURLConnection httpUrlConnection = (HttpURLConnection)new URL("http://www.mypage.org/upload.php").openConnection();

更改为

HttpURLConnection httpUrlConnection = (HttpURLConnection)new URL("http://www.mypage.org/upload.php?filename=abc.def").openConnection();

在您的 PHP 脚本中更改行

$filename="abc.xyz";

$filename=$_GET['filename'];

这个解决方案不使用任何外部库,在我看来比其他一些发布的更简单......

希望我能帮助任何人:)

【讨论】:

  • 哇!这就是简单的力量。完美无瑕、易于理解且功能强大。
  • 为什么不file_put_contents($filename,$fileData);
【解决方案2】:

这是一个旧线程,但为了其他人的利益,这里有一个 完全正常工作的示例,该示例正是操作所要求的:

PHP服务器代码:

<?php 

$target_path = "uploads/"; 

$target_path = $target_path . basename( $_FILES['uploadedfile']['name']); 

if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) { 
    echo "The file ". basename( $_FILES['uploadedfile']['name'])." has been uploaded"; 
} else{ 
    echo "There was an error uploading the file, please try again!"; 
}

?> 

Java 客户端代码:

import java.io.OutputStream;
import java.io.InputStream;
import java.net.URLConnection;
import java.net.URL;
import java.net.Socket;

public class Main {
    private final String CrLf = "\r\n";

    public static void main(String[] args) {
        Main main = new Main();
        main.httpConn();
    }

    private void httpConn() {
        URLConnection conn = null;
        OutputStream os = null;
        InputStream is = null;

        try {
            URL url = new URL("http://localhost/test/post.php");
            System.out.println("url:" + url);
            conn = url.openConnection();
            conn.setDoOutput(true);

            String postData = "";

            InputStream imgIs = getClass().getResourceAsStream("/test.jpg");
            byte[] imgData = new byte[imgIs.available()];
            imgIs.read(imgData);

            String message1 = "";
            message1 += "-----------------------------4664151417711" + CrLf;
            message1 += "Content-Disposition: form-data; name=\"uploadedfile\"; filename=\"test.jpg\""
                    + CrLf;
            message1 += "Content-Type: image/jpeg" + CrLf;
            message1 += CrLf;

            // the image is sent between the messages in the multipart message.

            String message2 = "";
            message2 += CrLf + "-----------------------------4664151417711--"
                    + CrLf;

            conn.setRequestProperty("Content-Type",
                    "multipart/form-data; boundary=---------------------------4664151417711");
            // might not need to specify the content-length when sending chunked
            // data.
            conn.setRequestProperty("Content-Length", String.valueOf((message1
                    .length() + message2.length() + imgData.length)));

            System.out.println("open os");
            os = conn.getOutputStream();

            System.out.println(message1);
            os.write(message1.getBytes());

            // SEND THE IMAGE
            int index = 0;
            int size = 1024;
            do {
                System.out.println("write:" + index);
                if ((index + size) > imgData.length) {
                    size = imgData.length - index;
                }
                os.write(imgData, index, size);
                index += size;
            } while (index < imgData.length);
            System.out.println("written:" + index);

            System.out.println(message2);
            os.write(message2.getBytes());
            os.flush();

            System.out.println("open is");
            is = conn.getInputStream();

            char buff = 512;
            int len;
            byte[] data = new byte[buff];
            do {
                System.out.println("READ");
                len = is.read(data);

                if (len > 0) {
                    System.out.println(new String(data, 0, len));
                }
            } while (len > 0);

            System.out.println("DONE");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("Close connection");
            try {
                os.close();
            } catch (Exception e) {
            }
            try {
                is.close();
            } catch (Exception e) {
            }
            try {

            } catch (Exception e) {
            }
        }
    }
}

您可以弄清楚如何为您的网站调整它,但我已经测试了上面的代码并且它可以工作。不过我不能把它归功于它>>See Original Post

【讨论】:

  • @CSchulz 如果我想发送一个文本文件,我应该把“Content-Type: image/jpeg”改成什么?
  • "text/plain" 如果您有 US ASCII,则可以使用,如果您需要另一个字符集,则需要指定它。
  • 为了与 Windows 7 兼容,将 InputStream imgIs = getClass().getResourceAsStream("/test.jpg"); 更改为 FileInputStream imgIs = new FileInputStream(new File("test.jpg"));
  • 我收到错误未定义索引:第 5 行 /var/www/html/upload/post.php 中的上传文件
【解决方案3】:

您需要为 PHP 使用表单多部分编码的帖子,以便能够按照您尝试的方式阅读它。 This 网站概述了一个很好的方法,并提供了可以帮助您的库的链接。

【讨论】:

    【解决方案4】:

    以上所有答案都是 100% 正确的。您也可以使用普通套接字,在这种情况下,您的方法将如下所示:

            // Compose the request header
            StringBuffer buf = new StringBuffer();
            buf.append("POST ");
            buf.append(uploader.getUploadAction());
            buf.append(" HTTP/1.1\r\n");
            buf.append("Content-Type: multipart/form-data; boundary=");
            buf.append(boundary);
            buf.append("\r\n");
            buf.append("Host: ");
            buf.append(uploader.getUploadHost());
            buf.append(':');
            buf.append(uploader.getUploadPort());
            buf.append("\r\n");
            buf.append("Connection: close\r\n");
            buf.append("Cache-Control: no-cache\r\n");
    
            // Add cookies
            List cookies = uploader.getCookies();
            if (!cookies.isEmpty())
                {
                    buf.append("Cookie: ");
                    for (Iterator iterator = cookies.iterator(); iterator.hasNext(); )
                        {
                            Parameter parameter = (Parameter)iterator.next();
    
                            buf.append(parameter.getName());
                            buf.append('=');
                            buf.append(parameter.getValue());
    
                            if (iterator.hasNext())
                                buf.append("; ");
                        }
    
                    buf.append("\r\n");
                }
    
            buf.append("Content-Length: ");
    
            // Request body
            StringBuffer body = new StringBuffer();
            List fields = uploader.getFields();
            for (Iterator iterator = fields.iterator(); iterator.hasNext();)
                {
    
                    Parameter parameter = (Parameter) iterator.next();
    
                    body.append("--");
                    body.append(boundary);
                    body.append("\r\n");
                    body.append("Content-Disposition: form-data; name=\"");
                    body.append(parameter.getName());
                    body.append("\"\r\n\r\n");
                    body.append(parameter.getValue());
                    body.append("\r\n");
                }
    
            body.append("--");
            body.append(boundary);
            body.append("\r\n");
            body.append("Content-Disposition: form-data; name=\"");
            body.append(uploader.getImageFieldName());
            body.append("\"; filename=\"");
            body.append(file.getName());
            body.append("\"\r\n");
            body.append("Content-Type: image/pjpeg\r\n\r\n");
    
            String boundary = "WHATEVERYOURDEARHEARTDESIRES";
            String lastBoundary = "\r\n--" + boundary + "--\r\n";
            long length = file.length() + (long) lastBoundary.length() + (long) body.length();
            long total = buf.length() + body.length();
    
            buf.append(length);
            buf.append("\r\n\r\n");
    
            // Upload here
            InetAddress address = InetAddress.getByName(uploader.getUploadHost());
            Socket socket = new Socket(address, uploader.getUploadPort());
            try
                {
                    socket.setSoTimeout(60 * 1000);
                    uploadStarted(length);
    
                    PrintStream out = new PrintStream(new BufferedOutputStream(socket.getOutputStream()));
                    out.print(buf);
                    out.print(body);
    
                    // Send the file
                    byte[] bytes = new byte[1024 * 65];
                    int size;
                    InputStream in = new BufferedInputStream(new FileInputStream(file));
                    try
                        {
                            while ((size = in.read(bytes)) > 0)
                                {
                                    total += size;
                                    out.write(bytes, 0, size);
                                    transferred(total);
                                }
                        }
                    finally
                        {
                            in.close();
                        }
    
                    out.print(lastBoundary);
                    out.flush();
    
                    // Read the response
                    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    while (reader.readLine() != null);
                }
            finally
                {
                    socket.close();
                }
    

    【讨论】:

    • 但不存在更简单的上传文件(或数据)的方法?
    • 就是这么简单。其他任何东西都只是使用库。
    • 找不到变量uploader
    【解决方案5】:

    我意识到这有点旧,但我刚刚发布了一个answer to a similar question,它也应该适用于这里。它包含类似于 Daniil 的代码,但使用 HttpURLConnection 而不是 Socket。

    【讨论】:

      【解决方案6】:

      您没有使用正确的 HTML 文件上传语义。您只是将一堆数据发布到 url。

      你有两个选择:

      • 您可以保持 Java 代码原样,并将 php 代码更改为仅将原始 POST 作为文件读取。
      • 更改 java 代码以进行真正的文件上传,可能使用common library

      我建议以符合标准的方式更改 Java 代码。

      【讨论】:

      • 谢谢,但我不想使用外部库...如何更改 php 代码以将原始 POST 作为文件读取?
      • 为此,您需要使用下面的套接字示例。请注意,这将是很多额外的代码,并且可能会花费大量时间进行调试。认真考虑您对外部库的厌恶。 (我知道有时你的手被束缚了,只是意识到这可能会容易得多)
      • 但不存在更简单的上传文件(或数据)的方法?
      猜你喜欢
      • 1970-01-01
      • 2011-11-03
      • 2021-08-28
      • 1970-01-01
      • 2017-12-06
      • 2012-06-18
      • 1970-01-01
      • 1970-01-01
      • 2023-01-12
      相关资源
      最近更新 更多