创建一个简单的 Java Web 服务器。图像未显示

发布于 2025-01-10 09:18:36 字数 1985 浏览 0 评论 0原文

我目前在大学(一年级)上学,被分配做 Java 服务器。目前,我已经创建了一个非常简单的 HTML 页面(Hello world 样式),文本显示在本地主机中。但是,当我将图像插入其中时,它不会显示...我知道标头应该“告诉”有一个图像来到服务器,以便它可以读取图像,但我该怎么做它?正如您在我的代码中看到的,作为最后的手段,我尝试传递该图像的第二个标头,但我也收到错误“SocketException”。如何通过 HTML 页面将图像和文本传递到我的网络服务器,以便它显示在我的本地主机上?

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

public class Server {
    public static void main(String[] args) {
        String pathImage = "www/1st.png";
        String pathHTML = "www/index.html";

        try {
            ServerSocket ss = new ServerSocket(9000);

            byte[] html = Files.readAllBytes(Paths.get(pathHTML));
            byte[] imageToBytes = Files.readAllBytes(Paths.get(pathImage));

            while (true) {
                Socket s = ss.accept();
                System.out.println("Connection: OK");
                BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
                System.out.println(in.readLine());

                DataOutputStream out = new DataOutputStream(s.getOutputStream());

                out.writeBytes("HTTP/1.0 200 Document Follows \r\n" +
                        "Content-Type: text/html; charset=UTF-8 \r\n" +
                        "Content-Length: " + html.length + "\r\n" +
                        "\r\n");

                out.write(html);
                out.flush();

                out.writeBytes("HTTP/1.0 200 Document Follows \r\n" +
                        "Content - Type: image/png > \r\n" +
                        "Content - Length: " + imageToBytes.length + "\r\n" +
                        "\r\n"); */

                out.write(imageToBytes);


                System.out.println("file has passed");
                out.flush();
                out.close();


            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

I'm currently in (1st year) college and was assigned to do Java Server. Currently, I have created a really simple HTML page (Hello world style) and text shows up in the Localhost. However, when I insert an image into it, it doesn't show up... I get that the header should "tell" that there's an image coming to the server so it can read an image as such, but how do I do it? As you can see by my code, as last resort, I tried to pass a second header for that image, but I also get an error "SocketException". How do I, through an HTML page, pass image and text to my webserver so it shows up on my localhost?

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

public class Server {
    public static void main(String[] args) {
        String pathImage = "www/1st.png";
        String pathHTML = "www/index.html";

        try {
            ServerSocket ss = new ServerSocket(9000);

            byte[] html = Files.readAllBytes(Paths.get(pathHTML));
            byte[] imageToBytes = Files.readAllBytes(Paths.get(pathImage));

            while (true) {
                Socket s = ss.accept();
                System.out.println("Connection: OK");
                BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
                System.out.println(in.readLine());

                DataOutputStream out = new DataOutputStream(s.getOutputStream());

                out.writeBytes("HTTP/1.0 200 Document Follows \r\n" +
                        "Content-Type: text/html; charset=UTF-8 \r\n" +
                        "Content-Length: " + html.length + "\r\n" +
                        "\r\n");

                out.write(html);
                out.flush();

                out.writeBytes("HTTP/1.0 200 Document Follows \r\n" +
                        "Content - Type: image/png > \r\n" +
                        "Content - Length: " + imageToBytes.length + "\r\n" +
                        "\r\n"); */

                out.write(imageToBytes);


                System.out.println("file has passed");
                out.flush();
                out.close();


            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

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

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

发布评论

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

评论(2

红玫瑰 2025-01-17 09:18:36

您成功地将一个简单的 HTML 页面传输到客户端。这是一个很好的基础。添加

<img src="..."/>

到 HTML 中,您将看到从服务器下载该 HTML 后,客户端会返回一个新连接,要求传送图像。第二个请求的响应必须仅为图像,而不是 HTML 页面。

因此,您需要区分客户的请求并提供正确的内容。

You succeeded in transferring a simple HTML page to the client. That is a good base. Add

<img src="..."/>

into the HTML and you will see that after downloading that HTML from your server the client comes back with a new connection, asking for the image to be delivered. The response on that second request must be the image only, not the HTML page.

So you need to distinguish what the client is requesting and serve the correct content.

我偏爱纯白色 2025-01-17 09:18:36

服务 HTTP 的套接字等待单个 HTTP 请求,然后为该请求提供单个响应。

您不能将所有响应转储到单个套接字中。您必须检查收到的请求,然后提供适合该请求的响应。

您必须做的第一件事是检查 InputStream 中的第一行。这是问候语行,格式必须为方法 路径 HTTP/版本

method 是标准 HTTP 请求方法(在您的程序中始终为 GET)。 路径基于浏览器中输入的URL,可能是www/index.htmlwww/1st.png版本1.01.12.0之一。

因此,您需要在执行其他操作之前解析该行:

String greeting = in.readLine();
if (greeting == null) {
    throw new IOException("Missing greeting.");
}

String[] parts = greeting.split(" ");
String requestPath = parts[1];

然后您可以根据该路径决定返回什么:

byte[] contentToReturn;
String contentType;
if (requestPath.endsWith("1st.png")) {
    contentToReturn = imageToBytes;
    contentType = "image/png";
} else 
    contentToReturn = html;
    contentType = "text/html; charset=UTF-8";
}

然后您必须仅将那个文件写入响应:

DataOutputStream out = new DataOutputStream(s.getOutputStream());

out.writeBytes("HTTP/1.0 200 Document Follows\r\n" +
        "Content-Type: " + contentType + "\r\n" +
        "Content-Length: " + contentToReturn.length + "\r\n" +
        "\r\n");

out.write(contentToReturn);
out.close();

浏览器将打开一个新的文件HTML 文件和 HTML 文件中引用的每个资源(例如图像)的套接字(即 HTTP 连接)。你只需要准备好为每一位服务。

其他一些要点:

  • 空间很重要。请勿在任何标题行末尾的 \r\n 之前添加空格。
  • 标题名称中的空格很重要。它是Content-Type,而不是Content - Type。第一种形式有效,另一种则无效。
  • 在关闭 OutputStream 之前无需刷新它。 close() 保证刷新所有剩余数据。

A socket serving HTTP waits for a single HTTP request, then provides a single response for that request.

You cannot just dump all of your responses into a single socket. You have to examine the request you have received, then provide a response which is appropriate for that request.

The first thing you must do is examine the first line in the InputStream. This is the greeting line, which must be in the format method path HTTP/version.

method is a standard HTTP request method (always GET in the case of your program). path is based on the URL entered into the browser, probably www/index.html or www/1st.png. version is one of 1.0, 1.1, or 2.0.

So you need to parse that line before you do anything else:

String greeting = in.readLine();
if (greeting == null) {
    throw new IOException("Missing greeting.");
}

String[] parts = greeting.split(" ");
String requestPath = parts[1];

Then you can decide what to return based on that path:

byte[] contentToReturn;
String contentType;
if (requestPath.endsWith("1st.png")) {
    contentToReturn = imageToBytes;
    contentType = "image/png";
} else 
    contentToReturn = html;
    contentType = "text/html; charset=UTF-8";
}

Then you must write only that one file to the response:

DataOutputStream out = new DataOutputStream(s.getOutputStream());

out.writeBytes("HTTP/1.0 200 Document Follows\r\n" +
        "Content-Type: " + contentType + "\r\n" +
        "Content-Length: " + contentToReturn.length + "\r\n" +
        "\r\n");

out.write(contentToReturn);
out.close();

The browser will open a new socket (that is, an HTTP connection) for the HTML file and for each resource (such as an image) referenced in the HTML file. You only have to be prepared to serve each one.

Some other points:

  • Spaces matter. Do not put a space at the end of any header line before the \r\n.
  • Spaces matter in header names. It's Content-Type, not Content - Type. The first form is valid, the other is not.
  • There is no need to flush an OutputStream before closing it. close() is guaranteed to flush any remaining data.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文