如何为 java 中的图像创建 http 响应?

How to create a http response for images in java?

我一直在尝试创建一个简单的 java 网络服务器,对于 html 或 css 等文件一切正常,但我无法正确发送图像响应。问题显然出在我发送的图像数据上,但我不确定如何正确执行。很长一段时间以来,我一直在搜索有关它的任何信息,但我就是找不到任何有用的信息来解决我的问题。

我的部分代码:

public void Send(String path) throws IOException {
    File file = new File(path);
    if(file.exists()) {
        if(!file.isDirectory()) {
            if(isImage(file)) {
                InputStream is = new FileInputStream(file);
                byte[] bytes = IOUtils.toByteArray(is);
                String response = "HTTP/1.1 200 OK" + CRLF + "Content-Length: " + bytes.length + CRLF;
                response += "content-type: image/jpeg" + CRLF + CRLF;
                outputStream.write(response.getBytes());
                outputStream.write(bytes);
                outputStream.write((CRLF + CRLF).getBytes());
                outputStream.flush();
            } else {
                String data = "";
                BufferedReader br = new BufferedReader(new FileReader(file));
                String st;
                while ((st = br.readLine()) != null) {
                    data += st;
                }
                int length = data.getBytes().length;
                String response = "HTTP/1.1 200 OK" + CRLF + "Content-Length: " + length + CRLF;
                response += CRLF + data + CRLF + CRLF;
                br.close();
                outputStream.write(response.getBytes());
            }
            return;
        }
    }
    SendError("404 Not Found");
}

outputStream is OutputStream from a Socket.

我看到了 this,但我认为我至少在图像部分只使用了流。

我是新手,如有任何帮助,我们将不胜感激!

编辑(更多信息):

浏览器信息:

Headers

Preview

isImage(file) 方法工作正常我已经测试过了,但这里是:

private boolean isImage(File file) {
    String mimetype = new MimetypesFileTypeMap().getContentType(file);
    String type = mimetype.split("/")[0];
    return type.equals("image");
}

图像是2.jpg

编辑 2

我写这段代码是为了将数组的内容写到一个文本文件中:

String out = "";
for(int i = 0; i < bytes.length; i++) {
    if(i%16 == 0) {
        out += "\n";
    }
    out += String.format("%02X ", bytes[i]);
}
BufferedWriter writer = new BufferedWriter(new FileWriter("test.txt"));
writer.write(out);
writer.close();

所以我检查了图像和数组的开头,它们似乎是相同的。

Start of the image data

Start if the array

之后我尝试创建一个客户端进行测试:

private static void Get2(String link) throws IOException {
    URL url = new URL(link);
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    con.setRequestMethod("GET");
    con.setRequestProperty("Connection", "keep-alive");
    con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 Edg/85.0.564.68");
    con.setRequestProperty("Accept", "image/webp,image/apng,image/*,*/*;q=0.8");
    con.setRequestProperty("Sec-Fetch-Site", "same-origin");
    con.setRequestProperty("Sec-Fetch-Mode", "no-cors");
    con.setRequestProperty("Sec-Fetch-Dest", "image");
    con.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
    con.setRequestProperty("Accept-Language", "sl,en;q=0.9,en-GB;q=0.8,en-US;q=0.7");
    
    con.setConnectTimeout(5000);
    con.setReadTimeout(5000);
    
    con.setInstanceFollowRedirects(false);
    
    int status = con.getResponseCode();
    
    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer content = new StringBuffer();
    int i = 0;
    while ((inputLine = in.readLine()) != null) {
        if(i < 5) {
            System.out.println(inputLine);
        } else {
            content.append(inputLine);
        }
        i++;
    }
    in.close();
    con.disconnect();

    BufferedWriter writer = new BufferedWriter(new FileWriter("test2.txt"));
    writer.write(content.toString());
    writer.close();
}

I called the function: Get2("http://localhost:8080/images/2.jpg");

并在 test2.txt 中获取了保存的数据。在里面我看到了类似数据的一些部分,但它显然有问题。我不确定我是否使用了这个客户端测试错误,所以如果我做错了什么或者应该使用其他东西让我知道。

Image (left test2.txt, right test.txt)

感谢所有愿意和已经提供帮助或有任何建议的人。

我终于想通了。其实是我没有提供一切的错。

String CRLF = "\n\r";

但显然,它应该只是\n。

我在某处读到 windows 会在 \n 之后自动添加 \r。我不知道这是不是真的但是删除 \r 解决了我的问题,因为我在 GET / HTTP/1.1 之后有 2 个空行所以其他内容被认为是数据的一部分。

一旦我改变一切正常。 再次感谢您的帮助!

编辑

没关系。我做错的是\n和\r的顺序。应该是 \r\n 而不是 \n\r