【问题标题】:How to retrieve an image from a web server (image/png header)如何从 Web 服务器检索图像(图像/png 标头)
【发布时间】:2020-01-20 12:17:16
【问题描述】:

我有一个带有 PHP 脚本的 Web 服务器,它为我提供了存储在服务器上的随机图像。此响应直接是具有以下标头的图像:

HTTP/1.1 200 OK
Date: Mon, 20 Jan 2020 12:10:05 GMT
Server: Apache/2.4.29 (Ubuntu)
Expires: Mon, 1 Jan 2099 00:00:00 GMT
Last-Modified: Mon, 20 Jan 2020 12:10:05 GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 971646
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: image/png

如您所见,服务器使用 MIME png 文件类型直接回复我。现在我想从一个 JAVA 程序中检索这个图像。我已经有一个代码可以让我从 http 请求中读取文本,但是如何保存来自网络的图像?

public class test {

    // one instance, reuse
    private final HttpClient httpClient = HttpClient.newBuilder()
            .version(HttpClient.Version.HTTP_2)
            .build();

    public static void main(String[] args) throws Exception {

        test obj = new test();

        System.out.println("Testing 1 - Send Http POST request");
        obj.sendPost();

    }

    private void sendPost() throws Exception {

        // form parameters
        Map<Object, Object> data = new HashMap<>();
        data.put("arg", "value");

        HttpRequest request = HttpRequest.newBuilder()
                .POST(buildFormDataFromMap(data))
                .uri(URI.create("url_here"))
                .setHeader("User-Agent", "Java 11 HttpClient Bot") // add request header
                .header("Content-Type", "application/x-www-form-urlencoded")
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

        // print status code
        System.out.println(response.statusCode());

        // print response body
                System.out.println(response.headers());

                try {
                    saveImage(response.body(), "path/to/file.png");
                }
                catch(IOException e) {
                    e.printStackTrace();
                }
        }

    public static void saveImage(String image, String destinationFile) throws IOException {     
            //What to write here ?
    }

    private static HttpRequest.BodyPublisher buildFormDataFromMap(Map<Object, Object> data) {
        var builder = new StringBuilder();
        for (Map.Entry<Object, Object> entry : data.entrySet()) {
            if (builder.length() > 0) {
                builder.append("&");
            }
            builder.append(URLEncoder.encode(entry.getKey().toString(), StandardCharsets.UTF_8));
            builder.append("=");
            builder.append(URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8));
                }

        return HttpRequest.BodyPublishers.ofString(builder.toString());
    }

感谢您的回复。

【问题讨论】:

  • 只是一个 2c,但除非服务器将图像作为 Base64 编码字符串发送,否则最简单的方法是将图像作为字节数组读取,然后将其写入文件。
  • 使用输入流下载任何文件类型,更多参考url
  • 非常感谢@Nazimch 你解决了我的问题

标签: java


【解决方案1】:

试试这个:

public static void saveImage(String imageUrl, String destinationFile) throws IOException {

    URL url = new URL(imageUrl);
    try(InputStream is = url.openStream();
    OutputStream os = new FileOutputStream(destinationFile)){

            byte[] b = new byte[2048];
            int length;

            while ((length = is.read(b)) != -1) {
                os.write(b, 0, length);
            }

            }catch(IOException  e){
            throw e;
            }
    }

Getting Image from URL (Java)

【讨论】:

  • 我无法使用它,因为我需要一个带参数的 POST 请求
  • 看看docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/…:// Receives the response body as an InputStream HttpResponse&lt;InputStream&gt; response = client .send(request, BodyHandlers.ofInputStream()); 然后将流写入文件。
  • 非常感谢@MarcStröbel 你解决了我的问题。
【解决方案2】:

我实际上编写了自己的 Http 客户端,它是名为 MgntUtils 的开源 Java 库的一部分,它允许您读取文本和二进制响应。您的代码可能如下所示:

HttpClient client = new HttpClient();
client.setContentType("application/json; charset=utf-8"); //set any appropriate content type (of the input if you send any information from the client to the server)
client.setRequestProperty("Authorization", "Bearer ey..."); // this is just an example of how to set any header if you need. You might not need to set any additional headers
ByteBuffer buff = client.sendHttpRequestForBinaryResponse("http://example.com/image",HttpMethod.POST, "bla bla"); //This is example of invoking method POST with some input data "bla bla", third parameter is not mandatory if you have no data to pass
ByteBuffer buff1 = client.sendHttpRequestForBinaryResponse("http://example.com/image",HttpMethod.GET); //This is an example of invoking GET method

我和其他一些人使用了这个库,它使用简单,运行良好。该库以 Maven 工件 here 和 GitHub 的形式提供,包括源代码和 JavaDoc here HttpClient 类的 JavaDoc 是 here

【讨论】:

    猜你喜欢
    • 2015-09-08
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2015-11-17
    • 2012-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多