通过 URLConnection 写入图像

发布于 2024-10-15 11:49:59 字数 1254 浏览 5 评论 0原文

我正在尝试通过 HttpURLConnection 写入图像。

我知道如何写文字,但我在尝试时遇到了真正的问题 写入图像

我已成功使用 ImageIO 写入本地 HD:

但我尝试通过 ImageIO 在 url 上写入图像,但失败了

URL url = new URL(uploadURL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-Type", "multipart/form-data;
                                            boundary=" + boundary);
output = new DataOutputStream(connection.getOutputStream());
output.writeBytes("--" + boundary + "\r\n");
output.writeBytes("Content-Disposition: form-data; name=\"" + FIELD_NAME + "\";
                                            filename=\"" + fileName + "\"\r\n");
output.writeBytes("Content-Type: " + dataMimeType + "\r\n");
output.writeBytes("Content-Transfer-Encoding: binary\r\n\r\n");
ImageIO.write(image, imageType, output);

uploadURL 是服务器上 asp 页面的 url,该页面将上传带有文件名的图像在“content-Disposition:部分中给出。

现在,当我发送此内容时,asp页面会找到请求并找到文件名。但没有找到要上传的文件。

问题是,当通过ImageIO在URL上写入时,会发生什么? ImageIO 正在写入的文件的名称,

所以请帮助我 ImageIO 如何在 URLConnection 上写入图像以及我如何知道我必须在 asp 页面中使用的文件的名称来上传文件

感谢您采取是时候阅读这篇文章了 迪利普·阿加瓦尔

I am trying to write an image over an HttpURLConnection.

I know how to write text but I am having real problems trying
to write an image

I have succeeded in writing to the local HD using ImageIO:

But I am trying to write Image by ImageIO on url and failed

URL url = new URL(uploadURL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-Type", "multipart/form-data;
                                            boundary=" + boundary);
output = new DataOutputStream(connection.getOutputStream());
output.writeBytes("--" + boundary + "\r\n");
output.writeBytes("Content-Disposition: form-data; name=\"" + FIELD_NAME + "\";
                                            filename=\"" + fileName + "\"\r\n");
output.writeBytes("Content-Type: " + dataMimeType + "\r\n");
output.writeBytes("Content-Transfer-Encoding: binary\r\n\r\n");
ImageIO.write(image, imageType, output);

the uploadURL is the url to an asp page on the server which will upload the image with the file name given in "content-Disposition: part.

now when I send this then asp page find the request and find the name of file. but does not find the file to be uploaded.

The problem is that when writing by ImageIO on URL what will the name of the file on which the ImageIO is writing,

So please help me how ImageIO will write an image on URLConnection and how can I know the name of the file which I have to use in the asp page to upload the file

Thanks for taking the time to read this post
Dilip Agarwal

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你是暖光i 2024-10-22 11:49:59

首先,我认为您应该在写入图像后调用 io.flush() ,然后调用 io.close() 。

第二种内容类型对我来说似乎很奇怪。看来您正在尝试提交表单,而它实际上是图像。我不知道您的 asp 期望什么,但通常当我编写通过 HTTP 传输文件的代码时,我会发送适当的内容类型,例如 image/jpeg

例如,下面是我从我编写的一个小实用程序中提取的代码片段,并在当前工作中使用:

    URL url = new URL("http://localhost:8080/handler");
    HttpURLConnection con = (HttpURLConnection)url.openConnection();
    con.setDoInput(true);
    con.setDoOutput(true);
    con.setUseCaches(false);
    con.setRequestProperty("Content-Type", "image/jpeg");
    con.setRequestMethod("POST");
    InputStream in = new FileInputStream("c:/temp/poc/img/mytest2.jpg");
    OutputStream out = con.getOutputStream();
    copy(in, con.getOutputStream());
    out.flush();
    out.close();
    BufferedReader r = new BufferedReader(new  InputStreamReader(con.getInputStream()));


            // obviously it is not required to print the response. But you have
            // to call con.getInputStream(). The connection is really established only
            // when getInputStream() is called.
    System.out.println("Output:");
    for (String line = r.readLine(); line != null;  line = r.readLine()) {
        System.out.println(line);
    }

我在这里使用了从 Jakarta IO utils 获取的方法 copy()。下面是供参考的代码:

protected static long copy(InputStream input, OutputStream output)
        throws IOException {
    byte[] buffer = new byte[12288]; // 12K
    long count = 0L;
    int n = 0;
    while (-1 != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
        count += n;
    }
    return count;
}

显然服务器端必须准备好直接从 POST body 读取图像内容。
我希望这有帮助。

First I believe that you should call io.flush() and then io.close() after writing image.

Second content type seems strange for me. It seems that you are trying to submit form while it is actually image. I do not know what does your asp expect but typically when I write code that should transfer file over HTTP I send appropriate content type, e.g. image/jpeg.

Here is for example code snippet I extracted from one small utility that I wrote and I am using during my current work:

    URL url = new URL("http://localhost:8080/handler");
    HttpURLConnection con = (HttpURLConnection)url.openConnection();
    con.setDoInput(true);
    con.setDoOutput(true);
    con.setUseCaches(false);
    con.setRequestProperty("Content-Type", "image/jpeg");
    con.setRequestMethod("POST");
    InputStream in = new FileInputStream("c:/temp/poc/img/mytest2.jpg");
    OutputStream out = con.getOutputStream();
    copy(in, con.getOutputStream());
    out.flush();
    out.close();
    BufferedReader r = new BufferedReader(new  InputStreamReader(con.getInputStream()));


            // obviously it is not required to print the response. But you have
            // to call con.getInputStream(). The connection is really established only
            // when getInputStream() is called.
    System.out.println("Output:");
    for (String line = r.readLine(); line != null;  line = r.readLine()) {
        System.out.println(line);
    }

I used here method copy() that I took from Jakarta IO utils. Here is the code for reference:

protected static long copy(InputStream input, OutputStream output)
        throws IOException {
    byte[] buffer = new byte[12288]; // 12K
    long count = 0L;
    int n = 0;
    while (-1 != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
        count += n;
    }
    return count;
}

Obviously the server side must be ready to read the image content directly from POST body.
I hope this helps.

新一帅帅 2024-10-22 11:49:59

OP 似乎已被遗忘,但为了 Kite 先生的利益:

// main method 
URL url = new URL(uploadURL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true); // triggers "POST"
// connection.setDoInput(true); // only if needed
connection.setUseCaches(false); // dunno
final String boundary = Long.toHexString(System.currentTimeMillis());
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary="
                                                                + boundary);
output = new DataOutputStream(connection.getOutputStream());
try {
     // image must be a File instance
    flushMultiPartData(image, output, boundary);
} catch (IOException e) {
    System.out.println("IOException in flushMultiPartData : " + e);
    return;
}
// ...
private void flushMultiPartData(File file, OutputStream serverOutputStream,
            String boundary) throws FileNotFoundException, IOException {
    // SEE https://stackoverflow.com/a/2793153/281545
    PrintWriter writer = null;
    try {
        // true = autoFlush, important!
        writer = new PrintWriter(new OutputStreamWriter(serverOutputStream,
                charsetForMultipartHeaders), true);
        appendBinary(file, boundary, writer, serverOutputStream);
        // End of multipart/form-data.
        writer.append("--" + boundary + "--").append(CRLF);
    } finally {
        if (writer != null) writer.close();
    }
}

private void appendBinary(File file, String boundary, PrintWriter writer,
        OutputStream output) throws FileNotFoundException, IOException {
    // Send binary file.
    writer.append("--" + boundary).append(CRLF);
    writer.append(
        "Content-Disposition: form-data; name=\"binaryFile\"; filename=\""
            + file.getName() + "\"").append(CRLF);
    writer.append("Content-Type: "
            +  URLConnection.guessContentTypeFromName(file.getName()))
            .append(CRLF);
    writer.append("Content-Transfer-Encoding: binary").append(CRLF);
    writer.append(CRLF).flush();
    InputStream input = null;
    try {
        input = new FileInputStream(file);
        byte[] buffer = new byte[1024];
        for (int length = 0; (length = input.read(buffer)) > 0;) {
            output.write(buffer, 0, length);
        }
        output.flush(); // Important! Output cannot be closed. Close of
        // writer will close output as well.
    } finally {
        if (input != null) try {
            input.close();
        } catch (IOException logOrIgnore) {}
    }
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of
    // binary boundary.
}

您可能需要添加 Gzip 压缩 - 请参阅 当我将其发布到时文件已损坏使用 GZIPOutputStream 的 servlet 用于具有或不具有 Gzip 的工作类。 ImageIO 这里没有位置 - 只需将字节写入线路并在服务器上使用 ImageIO 即可。基于@BalusC答案

The OP seems lost into oblivion but for the benefit of Mister Kite :

// main method 
URL url = new URL(uploadURL);
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true); // triggers "POST"
// connection.setDoInput(true); // only if needed
connection.setUseCaches(false); // dunno
final String boundary = Long.toHexString(System.currentTimeMillis());
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary="
                                                                + boundary);
output = new DataOutputStream(connection.getOutputStream());
try {
     // image must be a File instance
    flushMultiPartData(image, output, boundary);
} catch (IOException e) {
    System.out.println("IOException in flushMultiPartData : " + e);
    return;
}
// ...
private void flushMultiPartData(File file, OutputStream serverOutputStream,
            String boundary) throws FileNotFoundException, IOException {
    // SEE https://stackoverflow.com/a/2793153/281545
    PrintWriter writer = null;
    try {
        // true = autoFlush, important!
        writer = new PrintWriter(new OutputStreamWriter(serverOutputStream,
                charsetForMultipartHeaders), true);
        appendBinary(file, boundary, writer, serverOutputStream);
        // End of multipart/form-data.
        writer.append("--" + boundary + "--").append(CRLF);
    } finally {
        if (writer != null) writer.close();
    }
}

private void appendBinary(File file, String boundary, PrintWriter writer,
        OutputStream output) throws FileNotFoundException, IOException {
    // Send binary file.
    writer.append("--" + boundary).append(CRLF);
    writer.append(
        "Content-Disposition: form-data; name=\"binaryFile\"; filename=\""
            + file.getName() + "\"").append(CRLF);
    writer.append("Content-Type: "
            +  URLConnection.guessContentTypeFromName(file.getName()))
            .append(CRLF);
    writer.append("Content-Transfer-Encoding: binary").append(CRLF);
    writer.append(CRLF).flush();
    InputStream input = null;
    try {
        input = new FileInputStream(file);
        byte[] buffer = new byte[1024];
        for (int length = 0; (length = input.read(buffer)) > 0;) {
            output.write(buffer, 0, length);
        }
        output.flush(); // Important! Output cannot be closed. Close of
        // writer will close output as well.
    } finally {
        if (input != null) try {
            input.close();
        } catch (IOException logOrIgnore) {}
    }
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of
    // binary boundary.
}

You may want to add Gzip compression - see file corrupted when I post it to the servlet using GZIPOutputStream for a working class with or without Gzip. The ImageIO has no place here - just write the bytes past the wire and use ImageIO to your heart's content on the server. Based on @BalusC answer

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文