我正在 Web 编程类(class)中完成我的第一个作业项目,即用 Java 编写一个简单的 Web 服务器。我正处于来回传输数据的阶段,在未经训练的人看来,我的小型服务器似乎工作正常。但是,我找不到发送适当回复的方法。 (换句话说,无效的页面请求将显示 404 左右的 HTML 页面,但当我查看响应 header 时它仍然返回 200 OK 状态)。
我只能使用标准网络库进行套接字管理,并使用标准 I/O 库从输入流读取和写入字节和字符串。这是一些相关代码:
从我的主要...
ServerSocket servSocket = new ServerSocket(port, 10); // Bind the socket to the port
System.out.println("Opened port " + port + " successfully!");
while(true) {
//Accept the incoming socket, which means that the server process will
//wait until the client connects, then prepare to handle client commands
Socket newDataSocket = servSocket.accept();
System.out.println("Client socket created and connected to server socket...");
handleClient(newDataSocket); //Call handleClient method
}
来自handleClient方法...(在解析请求方法和路径的循环内)
if(checkURL.compareTo("/status") == 0) { // Check to see if status page has been requested
System.out.println("STATUS PAGE"); // TEMPORARY. JUST TO MAKE SURE WE ARE PROPERLY ACCESSING STATUS PAGE
sendFile("/status.html", dataStream);
}
else {
sendFile(checkURL, dataStream); // If not status, just try the input as a file name
}
从 sendFile 方法...
File f = new File(where); // Create the file object
if(f.exists() == true) { // Test if the file even exists so we can handle a 404 if not.
DataInputStream din;
try {
din = new DataInputStream(new FileInputStream(f));
int len = (int) f.length(); // Gets length of file in bytes
byte[] buf = new byte[len];
din.readFully(buf);
writer.write("HTTP/1.1 200 OK\r\n"); // Return status code for OK (200)
writer.write("Content-Length: " + len + "\r\n"); // WAS WRITING TO THE WRONG STREAM BEFORE!
writer.write("Content-Type: "+type+"\r\n\r\n\r\n"); // TODO VERIFY NEW CONTENT-TYPE CODE
out.write(buf); // Writes the FILE contents to the client
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace(); // Not really handled since that's not part of project spec, strictly for debug.
}
}
else {
writer.write("HTTP/1.1 404 Not Found\r\n"); // Attempting to handle 404 as simple as possible.
writer.write("Content-Type: text/html\r\n\r\n\r\n");
sendFile("/404.html", sock);
}
任何人都可以解释一下,在 sendFile 的条件中,我可以如何更改 404 block 中的响应(就像我之前所说,响应 header 仍然显示 200 OK)?这让我很烦恼,我只想使用 HTTPResponse 类,但我不能。 (此外,如果 f.exists == true,则不会显示内容长度和类型。)
谢谢!
最佳答案
编辑在我看来,在 404 情况下,您发送的内容如下:
HTTP/1.1 404 Not Found
Content-Type: text/html
HTTP/1.1 200 OK
Content-Length: 1234
Content-Type: text/html
...后面是 404 页面。请注意 404 后面的 200 行。这是因为您的 404 处理正在调用 sendFile
,它输出 200 响应状态代码。这可能会让接收者感到困惑。
错过了这一点的旧答案:
HTTP 响应以状态行开始,后跟(可选)一系列 header ,然后(可选)包含响应正文。状态行和标题只是定义格式的行,例如(随机选择一个示例):
HTTP/1.0 404 Not Found
要实现小型 HTTP 服务器,我建议通读 the spec并查看响应应该是什么样子。这有点概念上的飞跃,但它们实际上只是根据商定的格式返回的文本行。 (嗯,无论如何,几年前这对我来说是一个概念上的飞跃。我已经习惯了事情过于复杂的环境。)
从您最喜欢的命令行执行类似的操作也很有帮助:
telnet www.google.com 80
GET /thispagewontbefound
...然后按 Enter 键。你会得到这样的结果:
HTTP/1.0 404 Not Found
Content-Type: text/html; charset=UTF-8
X-Content-Type-Options: nosniff
Date: Sun, 12 Sep 2010 23:01:14 GMT
Server: sffe
Content-Length: 1361
X-XSS-Protection: 1; mode=block
...后面跟着一些 HTML 以提供友好的 404 页面。上面的第一行是状态行,其余的是标题。状态行/标题和第一行内容(例如页面)之间有一个空行。
关于java - 如何仅使用标准网络库发送 HTTP 响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3696986/