#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 прав, код ответа также должен быть написан. Довольно сложно кодировать все это вручную, когда вы можете использовать существующие продукты, но здесь это должно быть домашней работой.