Запись ответа сервера в браузер: Java

#java #http #browser #httpresponse

#java #http #браузер #httpresponse

Вопрос:

У меня есть простая серверная программа HTML, которая прослушивает запрос на порту 8000. Я хочу иметь возможность запрашивать HTML-файл из серверной программы и отправлять запрошенный HTML обратно в браузер. В настоящее время сервер получает запрос и анализирует запрошенное имя файла из запроса и даже выводит содержимое html-файла на консоль. Однако, когда я пытаюсь распечатать содержимое HTML-файла в сокет соединения (обратно в браузер), ничего не происходит; браузер просто продолжает загрузку.

Мой класс сервера относительно прост и просто создает экземпляры этого выполняемого класса RequestHandler для каждого соединения:

 package server;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class RequestHandler extends Thread {

    Object block;
    ServerSocket serverSocket;
    BufferedReader socketReader;
    PrintWriter socketWriter;

    public RequestHandler(Object block, ServerSocket serverSocket){
        this.block = block;
        this.serverSocket = serverSocket;
    }

    @Override
    public void run() {
        try{
            System.out.println("Waiting for request...");
            Socket clientSocket = serverSocket.accept();
            System.out.println("Connection made.");

            synchronized(block){
                System.out.print("Notifying server thread...");
                block.notify();
                System.out.println("...done");
                System.out.println();
            }

            socketReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));            
            socketWriter = new PrintWriter(clientSocket.getOutputStream(), true);

            String input;
            while((input = socketReader.readLine()) != null){
//              System.out.println(input);

                if(input.startsWith("GET")){
                    getResource(input);
                }
            }
        }catch(IOException e){
            System.out.println("IOException!");
            e.printStackTrace();
        }
    }

    public void getResource(String getRequest){
        String[] parts = getRequest.split("\s ");
        String filename = parts[1].substring(1);

        System.out.println(filename);
        File resource = new File(filename);             
        sendResponse(resource);
    }

    public void sendResponse(File resource){
        System.out.println(resource.getAbsolutePath());

        Scanner fileReader;
        try {
            fileReader = new Scanner(resource);

            while(fileReader.hasNext()){
                String line = fileReader.nextLine();
                System.out.println(line);
                socketWriter.println(line);
            }
        } catch (FileNotFoundException e) {
            System.out.println("File not found!");
            e.printStackTrace();
        }
    }

}
  

Комментарии:

1. Вы пытались предоставить HTTP-заголовки? Это может помочь…

2. Спецификация HTTP: w3.org/Protocols/rfc2616/rfc2616.html

3. Как вы выполняете вызов через браузер? каков формат URI ?

Ответ №1:

Что вы всегда должны делать, когда закончите запись или чтение из потока? (Я знаю ответ на ваш вопрос, но я задаю этот вопрос, потому что вы назвали свой вопрос «домашним заданием»)

Комментарии:

1. Он также должен написать что-то в сокет перед содержимым, если он хочет, чтобы HTML отображался, а не просто печатался как текст. Чтение RFC или учебника может помочь.

2. закрыл его, спасибо за предложение, о котором я думал ранее, но я подумал, что если я закрою поток, я по какой-то причине не смогу продолжать прослушивать дополнительные запросы. @AlexGitelman вы имеете в виду строку состояния «HTTP / 1.1 200 OK»?

3. @AlexGitelman Если вы хотите, чтобы браузер отображал ответ в виде веб-страницы HTML (вместо простого отображения HTML-кода в виде обычного текста), вы должны добавить заголовок к HTTP-ответу: Content-type: text/html

4. это была именно моя точка зрения. И @Chris прав, код ответа также должен быть написан. Довольно сложно кодировать все это вручную, когда вы можете использовать существующие продукты, но здесь это должно быть домашней работой.