java - 如何告诉浏览器它获取的数据是html而不是普通文本?

标签 java html sockets networking server

我编写了一个 Java 服务器应用程序,当浏览器请求该文件时,该应用程序会返回一个文件。浏览器向我的套接字发出 GET 请求,套接字返回文件。但是浏览器(在我的例子中是 firefox)将 html 文件视为常规文本文件,并且不渲染实际页面。这样浏览器就会显示整个html源代码。我该如何解决这个问题?

代码如下:

package ml.mindlabor.networking;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    static final int PORT = 9806;
    static final int MAX_BYTES_PER_STREAM = 10_000; // 10 kB
    static final String FILE_SYSTEM_PATH = "C:\\Users\\SBrau\\eclipse-workspace\\Networking\\src\\ml\\mindlabor\\networking\\Files\\public_html";

    static boolean running = true;

    ServerSocket ss = null;
    Socket soc = null;

    public static void main(String[] args) {
        Server server = new Server();

        // When the connection could not be established
        System.out.println("Waiting for connection ...");
        if (!server.connect()) return;

        server.listenForResponse();
    }

    public Server() {
        try {
            ss = new ServerSocket(PORT);
        } catch (IOException e) {
            System.err.println("Could not create ServerSocket on Port " + PORT);
            shutdown();
        }
    }

    boolean respond(String response) {
        try {
            PrintWriter out = new PrintWriter(soc.getOutputStream(), true);
            out.println(response);
            return true;
        } catch (IOException e) {
            System.err.println("Could not send to Port " + PORT);
        }
        return false;
    }

    boolean respond(byte[] response) {
        try {
            soc.getOutputStream().write(response);
            return true;
        } catch (IOException e) {
            System.err.println("Could not send to Port " + PORT);
        }
        return false;
    }

    boolean respondFile(String relPath) {
        String path = Server.FILE_SYSTEM_PATH + relPath;
        File file = new File(path);

        try {
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));

            byte[] buffer = new byte[(int)file.length()]; // or 4096, or more
            in.read(buffer, 0, buffer.length);
            soc.getOutputStream().write(buffer, 0, buffer.length);
            System.out.println("Loaded :D");
            in.close();
            soc.shutdownOutput();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    String rawDataToString(byte[] rawData) {
        return new String(rawData);
    }

    void listenForResponse() {
        new Thread(() -> {
            while (true) {
                try {
                    DataInputStream in = new DataInputStream(soc.getInputStream());

                    byte[] packetData = new byte[MAX_BYTES_PER_STREAM];
                    in.read(packetData);
                    receivedPackage(packetData);
                } catch (IOException e) {
                    System.err.println("Could not get data from port " + PORT);
                    shutdown();
                }
            }
        }).start();
    }

    void shutdown() {
        Server.running = false;
    }

    void receivedPackage(byte[] pkg) {
        String request = new String(pkg).trim();

        // GET Request for file
        if (request.contains("GET ")) {
            String[] arr = request.split(" ");
            respondFile(arr[1].trim());
        }
    }

    boolean connect() {
        try {
            soc = ss.accept();
            //soc.setKeepAlive(true);
            System.out.println("Connected!");
            return true;
        } catch (IOException e) {
            System.err.println("Could not wait for connection on port " + PORT);
            shutdown();
        }
        return false;
    }

}

最佳答案

好的。知道了。我通过重写以下方法解决了这个问题:

boolean respondFile(String relPath) {
    String path = Server.FILE_SYSTEM_PATH + relPath;
    File file = new File(path);

    try {
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
        PrintWriter out = new PrintWriter(soc.getOutputStream());
        BufferedOutputStream dataOut = new BufferedOutputStream(soc.getOutputStream());

        byte[] fileData = readFileData(file, (int)file.length());
        out.println("HTTP/1.1 501 Not Implemented");
        out.println("Content-type: text/html");
        out.println(); // blank line between headers and content, very important !
        out.flush();
        dataOut.write(fileData, 0, fileData.length);
        dataOut.flush();

        System.out.println("Loaded :D");
        in.close();
        soc.shutdownOutput();
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }

    return true;
}

private byte[] readFileData(File file, int fileLength) throws IOException {
    FileInputStream fileIn = null;
    byte[] fileData = new byte[fileLength];

    try {
        fileIn = new FileInputStream(file);
        fileIn.read(fileData);
    } finally {
        if (fileIn != null) 
            fileIn.close();
    }

    return fileData;
}

关于java - 如何告诉浏览器它获取的数据是html而不是普通文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59013827/

相关文章:

python - Python 使用 Socket 发送多个文件

java - Java 是否具有与 Objective-C 中的 @synthesize 等效的功能?

java - 如何将 JSON 字段名称映射到不同的对象字段名称?

jquery get 方法在 safari 中工作但在 firefox 中不起作用

c - 为什么我会收到一条警告说 "assignment makes pointer from integer without a cast"?

c - 多个 TCP 流相互干扰

java - 在 pom.xml 中获取错误

java - SQL Access 从两个表中选择 NOT IN

html - 如何响应地在另一个图像上缩放图像

php代码没有在adobe括号中缩进