【问题标题】:Java server send html page from file to browserJava服务器将html页面从文件发送到浏览器
【发布时间】:2020-07-30 04:42:51
【问题描述】:

我一直在尝试制作一个显示文件索引的 java 服务器。我正在创建一个 SocketServer 并将其连接到一个端口。然后创建一个充当客户端的 Socket,并创建一个连接到客户端的套接字输出流的 PrintWriter。如果我将页面硬编码到 PrintWriter,一切正常,但是当我尝试逐行读取文件并将其发送到 PrintWriter 时,什么都不会显示。

package com.github.masonnoyce;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Date;
import java.io.File;
import java.nio.file.Files;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.PrintWriter;


public class AServer
{
    public static void main (String[] args) throws Exception
    {
        AServer server = new AServer();
        int portNumber = 8080;
        //create server socket and say that it is running
        final ServerSocket myServer = new ServerSocket(portNumber);
        System.out.println("I have Connected To Port " + portNumber);

        boolean running = true;
        while(running)
        {
                //See if anyone connects
                try(Socket client = myServer.accept())
                {                    
                    server.sendPage(client);
                }
                catch(IOException e)
                {
                    System.out.println("Something went wrong streaming the page");
                    System.exit(1);
                }
        }
        try
        {
            myServer.close();
        }
        finally
        {
            System.out.println("Server Is now closed");
        }        
    }
    private void sendPage(Socket client) throws Exception
    {
        System.out.println("Page writter called");

        PrintWriter printWriter = new PrintWriter(client.getOutputStream());//Make a writer for the output stream to the client
        BufferedReader reader = new BufferedReader(new FileReader("path/to/index.html"));//grab a file and put it into the buffer
        String line = reader.readLine();//line to go line by line from file
        while(line != null)//repeat till the file is empty
        {
            printWriter.println(line);//print current line
            printWriter.flush();// I have also tried putting this outside the while loop right before 
            printWriter.close()
            line = reader.readLine();//read next line
        }
        reader.close();//close the reader
        printWriter.close();//Close the writer
//***********This section works if I replace the While loop With It**********//
//            printWriter.println("HTTP/1.1 200 OK");
//            printWriter.println("Content-Type: text/html");
//            printWriter.println("\r\n");
//            printWriter.println("<p> Hello world </p>");
//            printWriter.flush();//needed to actually send the data to the client
//            printWriter.close();//Close the writer
//************Above is the Hardcoding I was talking about****************************// 
    }    
} 

现在我知道服务器应该在一个线程上运行,从技术上讲,它目前永远无法退出,并且不需要某些导入。我现在不担心这个。我只需要弄清楚为什么 PrintWriter 在浏览器上显示 html 时不喜欢使用文件。我创建了一个调试 PrintWriter,它写入一个文件来测试我是否有正确的文件位置并且它可以使用它。

【问题讨论】:

    标签: java html file bufferedreader printwriter


    【解决方案1】:

    当您使用 Web 浏览器测试您的服务器时,您需要发送一个有效的 HTTP 请求,其中包括硬编码部分中提供的 HTTP 标头。

    因此,您应该在打印文件内容之前添加标题部分的输出。

    您还需要收集有关文件大小的信息,并发送"Content-Length: " + file_size + "\r\n" 标头。

    在读完页面文件之前关闭printWriter有一个bug,需要在循环结束后关闭:

        while(line != null)//repeat till the file is empty
        {
            printWriter.println(line);//print current line
            printWriter.flush();// I have also tried putting this outside the while loop right before 
            printWriter.close() // BUG: no ";" and closing printWriter too early
            line = reader.readLine();//read next line
        }
    

    因此,将文件发送到客户端的更新方法如下:

        private void sendPage(Socket client) throws Exception {
            System.out.println("Page writter called");
    
            File index = new File("index.html");
    
            PrintWriter printWriter = new PrintWriter(client.getOutputStream());// Make a writer for the output stream to
                                                                                // the client
            BufferedReader reader = new BufferedReader(new FileReader(index));// grab a file and put it into the buffer
            // print HTTP headers
            printWriter.println("HTTP/1.1 200 OK");
            printWriter.println("Content-Type: text/html");
            printWriter.println("Content-Length: " + index.length());
            printWriter.println("\r\n");
            String line = reader.readLine();// line to go line by line from file
            while (line != null)// repeat till the file is read
            {
                printWriter.println(line);// print current line
    
                line = reader.readLine();// read next line
            }
            reader.close();// close the reader
            printWriter.close();
        }
    

    【讨论】:

    • 谢谢,我不必使用 index.length(),但我相信它在处理更大的文件时会派上用场。我最大的问题是我试图在文件本身中将“HTTP/....”添加到“\r\n”。在代码中执行此操作,然后仅读取文件中的 http 即可完成这项工作。再次感谢!
    • 测试了当 HTTP 标头出现在文件中并且标头和正文之间有一个空行时的场景 - 它也工作正常 :)
    • @Msnoyce,如果您认为我的回答有帮助,请考虑将其标记为已接受 :) 谢谢!
    • 对不起。发布到 stackoverflow 的新手。我现在标记了。此外,关于添加文件长度的提示将在该项目的后面部分派上用场,再次感谢您!
    猜你喜欢
    • 2018-05-13
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    • 2013-11-19
    • 2021-10-22
    相关资源
    最近更新 更多